Bug Summary

File:xmlschemas.c
Warning:line 23366, column 8
Value stored to 'res' is never read

Annotated Source Code

Press '?' to see keyboard shortcuts

clang -cc1 -cc1 -triple x86_64-unknown-linux-gnu -analyze -disable-free -clear-ast-before-backend -disable-llvm-verifier -discard-value-names -main-file-name xmlschemas.c -analyzer-checker=core -analyzer-checker=apiModeling -analyzer-checker=unix -analyzer-checker=deadcode -analyzer-checker=security.insecureAPI.UncheckedReturn -analyzer-checker=security.insecureAPI.getpw -analyzer-checker=security.insecureAPI.gets -analyzer-checker=security.insecureAPI.mktemp -analyzer-checker=security.insecureAPI.mkstemp -analyzer-checker=security.insecureAPI.vfork -analyzer-checker=nullability.NullPassedToNonnull -analyzer-checker=nullability.NullReturnedFromNonnull -analyzer-output plist -w -setup-static-analyzer -mrelocation-model pic -pic-level 2 -fhalf-no-semantic-interposition -mframe-pointer=none -fmath-errno -ffp-contract=on -fno-rounding-math -mconstructor-aliases -funwind-tables=2 -target-cpu x86-64 -tune-cpu generic -debugger-tuning=gdb -fdebug-compilation-dir=/src/libxml2 -fcoverage-compilation-dir=/src/libxml2 -resource-dir /usr/lib/llvm-20.1/lib64/clang/20 -D HAVE_CONFIG_H -I . -I ./include -I ./include -D SYSCONFDIR="/usr/local/etc" -D _REENTRANT -D PIC -internal-isystem /usr/lib/llvm-20.1/lib64/clang/20/include -internal-isystem /usr/local/include -internal-isystem /usr/lib64/gcc/x86_64-alt-linux/14/../../../../x86_64-alt-linux/include -internal-externc-isystem /include -internal-externc-isystem /usr/include -O2 -Wwrite-strings -Wno-long-long -Wno-format-extra-args -fconst-strings -ferror-limit 19 -fgnuc-version=4.2.1 -fskip-odr-check-in-gmf -vectorize-loops -vectorize-slp -analyzer-output=html -faddrsig -D__GCC_HAVE_DWARF2_CFI_ASM=1 -o /report/2026-02-20-185044-1-1 -x c xmlschemas.c
1/*
2 * schemas.c : implementation of the XML Schema handling and
3 * schema validity checking
4 *
5 * See Copyright for the status of this software.
6 *
7 * Daniel Veillard <veillard@redhat.com>
8 */
9
10/*
11 * TODO:
12 * - when types are redefined in includes, check that all
13 * types in the redef list are equal
14 * -> need a type equality operation.
15 * - if we don't intend to use the schema for schemas, we
16 * need to validate all schema attributes (ref, type, name)
17 * against their types.
18 * - Eliminate item creation for: ??
19 *
20 * URGENT TODO:
21 * - For xsi-driven schema acquisition, augment the IDCs after every
22 * acquisition episode (xmlSchemaAugmentIDC).
23 *
24 * NOTES:
25 * - Eliminated item creation for: <restriction>, <extension>,
26 * <simpleContent>, <complexContent>, <list>, <union>
27 *
28 * PROBLEMS:
29 * - http://lists.w3.org/Archives/Public/www-xml-schema-comments/2005JulSep/0337.html
30 * IDC XPath expression and chameleon includes: the targetNamespace is changed, so
31 * XPath will have trouble to resolve to this namespace, since not known.
32 *
33 *
34 * CONSTRAINTS:
35 *
36 * Schema Component Constraint:
37 * All Group Limited (cos-all-limited)
38 * Status: complete
39 * (1.2)
40 * In xmlSchemaGroupDefReferenceTermFixup() and
41 * (2)
42 * In xmlSchemaParseModelGroup()
43 * TODO: Actually this should go to component-level checks,
44 * but is done here due to performance. Move it to an other layer
45 * is schema construction via an API is implemented.
46 */
47
48/* To avoid EBCDIC trouble when parsing on zOS */
49#if defined(__MVS__)
50#pragma convert("ISO8859-1")
51#endif
52
53#define IN_LIBXML
54#include "libxml.h"
55
56#ifdef LIBXML_SCHEMAS_ENABLED
57
58#include <string.h>
59#include <libxml/xmlmemory.h>
60#include <libxml/parser.h>
61#include <libxml/parserInternals.h>
62#include <libxml/hash.h>
63#include <libxml/uri.h>
64#include <libxml/xmlschemas.h>
65#include <libxml/schemasInternals.h>
66#include <libxml/xmlschemastypes.h>
67#include <libxml/xmlautomata.h>
68#include <libxml/xmlregexp.h>
69#include <libxml/dict.h>
70#include <libxml/encoding.h>
71#include <libxml/xmlIO.h>
72#ifdef LIBXML_PATTERN_ENABLED
73#include <libxml/pattern.h>
74#endif
75#ifdef LIBXML_READER_ENABLED
76#include <libxml/xmlreader.h>
77#endif
78
79#include "private/error.h"
80#include "private/string.h"
81
82/* #define WXS_ELEM_DECL_CONS_ENABLED */
83
84/* #define ENABLE_PARTICLE_RESTRICTION 1 */
85
86#define ENABLE_REDEFINE
87
88/* #define ENABLE_NAMED_LOCALS */
89
90/* #define ENABLE_IDC_NODE_TABLES_TEST */
91
92#define DUMP_CONTENT_MODEL
93
94#ifdef LIBXML_READER_ENABLED
95/* #define XML_SCHEMA_READER_ENABLED */
96#endif
97
98#define UNBOUNDED(1 << 30) (1 << 30)
99#define TODO(*__xmlGenericError())((*__xmlGenericErrorContext()), "Unimplemented block at %s:%d\n"
, "xmlschemas.c", 99);
\
100 xmlGenericError(*__xmlGenericError())(xmlGenericErrorContext(*__xmlGenericErrorContext()), \
101 "Unimplemented block at %s:%d\n", \
102 __FILE__"xmlschemas.c", __LINE__102);
103
104#define XML_SCHEMAS_NO_NAMESPACE(const xmlChar *) "##" (const xmlChar *) "##"
105
106/*
107 * The XML Schemas namespaces
108 */
109static const xmlChar *xmlSchemaNs = (const xmlChar *)
110 "http://www.w3.org/2001/XMLSchema";
111
112static const xmlChar *xmlSchemaInstanceNs = (const xmlChar *)
113 "http://www.w3.org/2001/XMLSchema-instance";
114
115static const xmlChar *xmlNamespaceNs = (const xmlChar *)
116 "http://www.w3.org/2000/xmlns/";
117
118/*
119* Come casting macros.
120*/
121#define ACTXT_CAST(xmlSchemaAbstractCtxtPtr) (xmlSchemaAbstractCtxtPtr)
122#define PCTXT_CAST(xmlSchemaParserCtxtPtr) (xmlSchemaParserCtxtPtr)
123#define VCTXT_CAST(xmlSchemaValidCtxtPtr) (xmlSchemaValidCtxtPtr)
124#define WXS_BASIC_CAST(xmlSchemaBasicItemPtr) (xmlSchemaBasicItemPtr)
125#define WXS_TREE_CAST(xmlSchemaTreeItemPtr) (xmlSchemaTreeItemPtr)
126#define WXS_PTC_CAST(xmlSchemaParticlePtr) (xmlSchemaParticlePtr)
127#define WXS_TYPE_CAST(xmlSchemaTypePtr) (xmlSchemaTypePtr)
128#define WXS_ELEM_CAST(xmlSchemaElementPtr) (xmlSchemaElementPtr)
129#define WXS_ATTR_GROUP_CAST(xmlSchemaAttributeGroupPtr) (xmlSchemaAttributeGroupPtr)
130#define WXS_ATTR_CAST(xmlSchemaAttributePtr) (xmlSchemaAttributePtr)
131#define WXS_ATTR_USE_CAST(xmlSchemaAttributeUsePtr) (xmlSchemaAttributeUsePtr)
132#define WXS_ATTR_PROHIB_CAST(xmlSchemaAttributeUseProhibPtr) (xmlSchemaAttributeUseProhibPtr)
133#define WXS_MODEL_GROUPDEF_CAST(xmlSchemaModelGroupDefPtr) (xmlSchemaModelGroupDefPtr)
134#define WXS_MODEL_GROUP_CAST(xmlSchemaModelGroupPtr) (xmlSchemaModelGroupPtr)
135#define WXS_IDC_CAST(xmlSchemaIDCPtr) (xmlSchemaIDCPtr)
136#define WXS_QNAME_CAST(xmlSchemaQNameRefPtr) (xmlSchemaQNameRefPtr)
137#define WXS_LIST_CAST(xmlSchemaItemListPtr) (xmlSchemaItemListPtr)
138
139/*
140* Macros to query common properties of components.
141*/
142#define WXS_ITEM_NODE(i)xmlSchemaGetComponentNode((xmlSchemaBasicItemPtr) (i)) xmlSchemaGetComponentNode(WXS_BASIC_CAST(xmlSchemaBasicItemPtr) (i))
143
144#define WXS_ITEM_TYPE_NAME(i)xmlSchemaGetComponentTypeStr((xmlSchemaBasicItemPtr) (i)) xmlSchemaGetComponentTypeStr(WXS_BASIC_CAST(xmlSchemaBasicItemPtr) (i))
145/*
146* Macros for element declarations.
147*/
148#define WXS_ELEM_TYPEDEF(e)(e)->subtypes (e)->subtypes
149
150#define WXS_SUBST_HEAD(item)(item)->refDecl (item)->refDecl
151/*
152* Macros for attribute declarations.
153*/
154#define WXS_ATTR_TYPEDEF(a)(a)->subtypes (a)->subtypes
155/*
156* Macros for attribute uses.
157*/
158#define WXS_ATTRUSE_DECL(au)((xmlSchemaAttributeUsePtr) (au))->attrDecl (WXS_ATTR_USE_CAST(xmlSchemaAttributeUsePtr) (au))->attrDecl
159
160#define WXS_ATTRUSE_TYPEDEF(au)(((xmlSchemaAttributeUsePtr) ((xmlSchemaAttributeUsePtr) au))
->attrDecl)->subtypes
WXS_ATTR_TYPEDEF(WXS_ATTRUSE_DECL( WXS_ATTR_USE_CAST au))(((xmlSchemaAttributeUsePtr) ((xmlSchemaAttributeUsePtr) au))
->attrDecl)->subtypes
161
162#define WXS_ATTRUSE_DECL_NAME(au)(((xmlSchemaAttributeUsePtr) (au))->attrDecl)->name (WXS_ATTRUSE_DECL(au)((xmlSchemaAttributeUsePtr) (au))->attrDecl)->name
163
164#define WXS_ATTRUSE_DECL_TNS(au)(((xmlSchemaAttributeUsePtr) (au))->attrDecl)->targetNamespace (WXS_ATTRUSE_DECL(au)((xmlSchemaAttributeUsePtr) (au))->attrDecl)->targetNamespace
165/*
166* Macros for attribute groups.
167*/
168#define WXS_ATTR_GROUP_HAS_REFS(ag)(((xmlSchemaAttributeGroupPtr) (ag))->flags & 1 <<
4)
((WXS_ATTR_GROUP_CAST(xmlSchemaAttributeGroupPtr) (ag))->flags & XML_SCHEMAS_ATTRGROUP_HAS_REFS1 << 4)
169#define WXS_ATTR_GROUP_EXPANDED(ag)(((xmlSchemaAttributeGroupPtr) (ag))->flags & 1 <<
0)
((WXS_ATTR_GROUP_CAST(xmlSchemaAttributeGroupPtr) (ag))->flags & XML_SCHEMAS_ATTRGROUP_WILDCARD_BUILDED1 << 0)
170/*
171* Macros for particles.
172*/
173#define WXS_PARTICLE(p)(xmlSchemaParticlePtr) (p) WXS_PTC_CAST(xmlSchemaParticlePtr) (p)
174
175#define WXS_PARTICLE_TERM(p)((xmlSchemaParticlePtr) (p))->children (WXS_PARTICLE(p)(xmlSchemaParticlePtr) (p))->children
176
177#define WXS_PARTICLE_TERM_AS_ELEM(p)((xmlSchemaElementPtr) ((xmlSchemaParticlePtr) (p))->children
)
(WXS_ELEM_CAST(xmlSchemaElementPtr) WXS_PARTICLE_TERM(p)((xmlSchemaParticlePtr) (p))->children)
178
179#define WXS_PARTICLE_MODEL(p)(xmlSchemaModelGroupPtr) (xmlSchemaParticlePtr) (p)->children WXS_MODEL_GROUP_CAST(xmlSchemaModelGroupPtr) WXS_PARTICLE(p)(xmlSchemaParticlePtr) (p)->children
180/*
181* Macros for model groups definitions.
182*/
183#define WXS_MODELGROUPDEF_MODEL(mgd)((xmlSchemaModelGroupPtr) (mgd))->children (WXS_MODEL_GROUP_CAST(xmlSchemaModelGroupPtr) (mgd))->children
184/*
185* Macros for model groups.
186*/
187#define WXS_IS_MODEL_GROUP(i)(((i)->type == XML_SCHEMA_TYPE_SEQUENCE) || ((i)->type ==
XML_SCHEMA_TYPE_CHOICE) || ((i)->type == XML_SCHEMA_TYPE_ALL
))
\
188 (((i)->type == XML_SCHEMA_TYPE_SEQUENCE) || \
189 ((i)->type == XML_SCHEMA_TYPE_CHOICE) || \
190 ((i)->type == XML_SCHEMA_TYPE_ALL))
191
192#define WXS_MODELGROUP_PARTICLE(mg)(xmlSchemaParticlePtr) (mg)->children WXS_PTC_CAST(xmlSchemaParticlePtr) (mg)->children
193/*
194* Macros for schema buckets.
195*/
196#define WXS_IS_BUCKET_INCREDEF(t)(((t) == 2) || ((t) == 3)) (((t) == XML_SCHEMA_SCHEMA_INCLUDE2) || \
197 ((t) == XML_SCHEMA_SCHEMA_REDEFINE3))
198
199#define WXS_IS_BUCKET_IMPMAIN(t)(((t) == 0) || ((t) == 1)) (((t) == XML_SCHEMA_SCHEMA_MAIN0) || \
200 ((t) == XML_SCHEMA_SCHEMA_IMPORT1))
201
202#define WXS_IMPBUCKET(b)((xmlSchemaImportPtr) (b)) ((xmlSchemaImportPtr) (b))
203
204#define WXS_INCBUCKET(b)((xmlSchemaIncludePtr) (b)) ((xmlSchemaIncludePtr) (b))
205/*
206* Macros for complex/simple types.
207*/
208#define WXS_IS_ANYTYPE(i)(( (i)->type == XML_SCHEMA_TYPE_BASIC) && ( ((xmlSchemaTypePtr
) (i))->builtInType == XML_SCHEMAS_ANYTYPE))
\
209 (( (i)->type == XML_SCHEMA_TYPE_BASIC) && \
210 ( (WXS_TYPE_CAST(xmlSchemaTypePtr) (i))->builtInType == XML_SCHEMAS_ANYTYPE))
211
212#define WXS_IS_COMPLEX(i)(((i)->type == XML_SCHEMA_TYPE_COMPLEX) || ((i)->builtInType
== XML_SCHEMAS_ANYTYPE))
\
213 (((i)->type == XML_SCHEMA_TYPE_COMPLEX) || \
214 ((i)->builtInType == XML_SCHEMAS_ANYTYPE))
215
216#define WXS_IS_SIMPLE(item)((item->type == XML_SCHEMA_TYPE_SIMPLE) || ((item->type
== XML_SCHEMA_TYPE_BASIC) && (item->builtInType !=
XML_SCHEMAS_ANYTYPE)))
\
217 ((item->type == XML_SCHEMA_TYPE_SIMPLE) || \
218 ((item->type == XML_SCHEMA_TYPE_BASIC) && \
219 (item->builtInType != XML_SCHEMAS_ANYTYPE)))
220
221#define WXS_IS_ANY_SIMPLE_TYPE(i)(((i)->type == XML_SCHEMA_TYPE_BASIC) && ((i)->
builtInType == XML_SCHEMAS_ANYSIMPLETYPE))
\
222 (((i)->type == XML_SCHEMA_TYPE_BASIC) && \
223 ((i)->builtInType == XML_SCHEMAS_ANYSIMPLETYPE))
224
225#define WXS_IS_RESTRICTION(t)((t)->flags & 1 << 2) \
226 ((t)->flags & XML_SCHEMAS_TYPE_DERIVATION_METHOD_RESTRICTION1 << 2)
227
228#define WXS_IS_EXTENSION(t)((t)->flags & 1 << 1) \
229 ((t)->flags & XML_SCHEMAS_TYPE_DERIVATION_METHOD_EXTENSION1 << 1)
230
231#define WXS_IS_TYPE_NOT_FIXED(i)(((i)->type != XML_SCHEMA_TYPE_BASIC) && (((i)->
flags & 1 << 22) == 0))
\
232 (((i)->type != XML_SCHEMA_TYPE_BASIC) && \
233 (((i)->flags & XML_SCHEMAS_TYPE_INTERNAL_RESOLVED1 << 22) == 0))
234
235#define WXS_IS_TYPE_NOT_FIXED_1(item)(((item)->type != XML_SCHEMA_TYPE_BASIC) && (((item
)->flags & 1 << 29) == 0))
\
236 (((item)->type != XML_SCHEMA_TYPE_BASIC) && \
237 (((item)->flags & XML_SCHEMAS_TYPE_FIXUP_11 << 29) == 0))
238
239#define WXS_TYPE_IS_GLOBAL(t)((t)->flags & 1 << 3) ((t)->flags & XML_SCHEMAS_TYPE_GLOBAL1 << 3)
240
241#define WXS_TYPE_IS_LOCAL(t)(((t)->flags & 1 << 3) == 0) (((t)->flags & XML_SCHEMAS_TYPE_GLOBAL1 << 3) == 0)
242/*
243* Macros for exclusively for complex types.
244*/
245#define WXS_HAS_COMPLEX_CONTENT(item)((item->contentType == XML_SCHEMA_CONTENT_MIXED) || (item->
contentType == XML_SCHEMA_CONTENT_EMPTY) || (item->contentType
== XML_SCHEMA_CONTENT_ELEMENTS))
\
246 ((item->contentType == XML_SCHEMA_CONTENT_MIXED) || \
247 (item->contentType == XML_SCHEMA_CONTENT_EMPTY) || \
248 (item->contentType == XML_SCHEMA_CONTENT_ELEMENTS))
249
250#define WXS_HAS_SIMPLE_CONTENT(item)((item->contentType == XML_SCHEMA_CONTENT_SIMPLE) || (item
->contentType == XML_SCHEMA_CONTENT_BASIC))
\
251 ((item->contentType == XML_SCHEMA_CONTENT_SIMPLE) || \
252 (item->contentType == XML_SCHEMA_CONTENT_BASIC))
253
254#define WXS_HAS_MIXED_CONTENT(item)(item->contentType == XML_SCHEMA_CONTENT_MIXED) \
255 (item->contentType == XML_SCHEMA_CONTENT_MIXED)
256
257#define WXS_EMPTIABLE(t)(xmlSchemaIsParticleEmptiable((xmlSchemaParticlePtr) (t)->
subtypes))
\
258 (xmlSchemaIsParticleEmptiable(WXS_PTC_CAST(xmlSchemaParticlePtr) (t)->subtypes))
259
260#define WXS_TYPE_CONTENTTYPE(t)(t)->subtypes (t)->subtypes
261
262#define WXS_TYPE_PARTICLE(t)(xmlSchemaParticlePtr) (t)->subtypes WXS_PTC_CAST(xmlSchemaParticlePtr) (t)->subtypes
263
264#define WXS_TYPE_PARTICLE_TERM(t)((xmlSchemaParticlePtr) ((xmlSchemaParticlePtr) (t)->subtypes
))->children
WXS_PARTICLE_TERM(WXS_TYPE_PARTICLE(t))((xmlSchemaParticlePtr) ((xmlSchemaParticlePtr) (t)->subtypes
))->children
265/*
266* Macros for exclusively for simple types.
267*/
268#define WXS_LIST_ITEMTYPE(t)(t)->subtypes (t)->subtypes
269
270#define WXS_IS_ATOMIC(t)(t->flags & 1 << 8) (t->flags & XML_SCHEMAS_TYPE_VARIETY_ATOMIC1 << 8)
271
272#define WXS_IS_LIST(t)(t->flags & 1 << 6) (t->flags & XML_SCHEMAS_TYPE_VARIETY_LIST1 << 6)
273
274#define WXS_IS_UNION(t)(t->flags & 1 << 7) (t->flags & XML_SCHEMAS_TYPE_VARIETY_UNION1 << 7)
275/*
276* Misc parser context macros.
277*/
278#define WXS_CONSTRUCTOR(ctx)(ctx)->constructor (ctx)->constructor
279
280#define WXS_HAS_BUCKETS(ctx)( (((ctx))->constructor->buckets != ((void*)0)) &&
(((ctx))->constructor->buckets->nbItems > 0) )
\
281( (WXS_CONSTRUCTOR((ctx))((ctx))->constructor->buckets != NULL((void*)0)) && \
282(WXS_CONSTRUCTOR((ctx))((ctx))->constructor->buckets->nbItems > 0) )
283
284#define WXS_SUBST_GROUPS(ctx)((ctx))->constructor->substGroups WXS_CONSTRUCTOR((ctx))((ctx))->constructor->substGroups
285
286#define WXS_BUCKET(ctx)((ctx))->constructor->bucket WXS_CONSTRUCTOR((ctx))((ctx))->constructor->bucket
287
288#define WXS_SCHEMA(ctx)(ctx)->schema (ctx)->schema
289
290#define WXS_ADD_LOCAL(ctx, item)do { if (xmlSchemaAddItemSize(&(((ctx))->constructor->
bucket->locals), 10, item) < 0) { xmlFree(item); item =
((void*)0); } } while (0)
\
291 do { \
292 if (xmlSchemaAddItemSize(&(WXS_BUCKET(ctx)((ctx))->constructor->bucket->locals), 10, item) < 0) { \
293 xmlFree(item); \
294 item = NULL((void*)0); \
295 } \
296 } while (0)
297
298#define WXS_ADD_GLOBAL(ctx, item)do { if (xmlSchemaAddItemSize(&(((ctx))->constructor->
bucket->globals), 5, item) < 0) { xmlFree(item); item =
((void*)0); } } while (0)
\
299 do { \
300 if (xmlSchemaAddItemSize(&(WXS_BUCKET(ctx)((ctx))->constructor->bucket->globals), 5, item) < 0) { \
301 xmlFree(item); \
302 item = NULL((void*)0); \
303 } \
304 } while (0)
305
306#define WXS_ADD_PENDING(ctx, item)xmlSchemaAddItemSize(&((ctx)->constructor->pending)
, 10, item)
\
307 xmlSchemaAddItemSize(&((ctx)->constructor->pending), 10, item)
308/*
309* xmlSchemaItemList macros.
310*/
311#define WXS_ILIST_IS_EMPTY(l)((l == ((void*)0)) || ((l)->nbItems == 0)) ((l == NULL((void*)0)) || ((l)->nbItems == 0))
312/*
313* Misc macros.
314*/
315#define IS_SCHEMA(node, type)((node != ((void*)0)) && (node->ns != ((void*)0)) &&
(xmlStrEqual(node->name, (const xmlChar *) type)) &&
(xmlStrEqual(node->ns->href, xmlSchemaNs)))
\
316 ((node != NULL((void*)0)) && (node->ns != NULL((void*)0)) && \
317 (xmlStrEqual(node->name, (const xmlChar *) type)) && \
318 (xmlStrEqual(node->ns->href, xmlSchemaNs)))
319
320#define FREE_AND_NULL(str)if ((str) != ((void*)0)) { xmlFree((xmlChar *) (str)); str = (
(void*)0); }
if ((str) != NULL((void*)0)) { xmlFree((xmlChar *) (str)); str = NULL((void*)0); }
321
322/*
323* Since we put the default/fixed values into the dict, we can
324* use pointer comparison for those values.
325* REMOVED: (xmlStrEqual((v1), (v2)))
326*/
327#define WXS_ARE_DEFAULT_STR_EQUAL(v1, v2)((v1) == (v2)) ((v1) == (v2))
328
329#define INODE_NILLED(item)(item->flags & 1<<2) (item->flags & XML_SCHEMA_ELEM_INFO_NILLED1<<2)
330
331#define CAN_PARSE_SCHEMA(b)(((b)->doc != ((void*)0)) && ((b)->parsed == 0)
)
(((b)->doc != NULL((void*)0)) && ((b)->parsed == 0))
332
333#define HFAILUREif (res == -1) goto exit_failure; if (res == -1) goto exit_failure;
334
335#define HERRORif (res != 0) goto exit_error; if (res != 0) goto exit_error;
336
337#define HSTOP(ctx)if ((ctx)->stop) goto exit; if ((ctx)->stop) goto exit;
338/*
339* Some flags used for various schema constraints.
340*/
341#define SUBSET_RESTRICTION1<<0 1<<0
342#define SUBSET_EXTENSION1<<1 1<<1
343#define SUBSET_SUBSTITUTION1<<2 1<<2
344#define SUBSET_LIST1<<3 1<<3
345#define SUBSET_UNION1<<4 1<<4
346
347typedef struct _xmlSchemaNodeInfo xmlSchemaNodeInfo;
348typedef xmlSchemaNodeInfo *xmlSchemaNodeInfoPtr;
349
350typedef struct _xmlSchemaItemList xmlSchemaItemList;
351typedef xmlSchemaItemList *xmlSchemaItemListPtr;
352struct _xmlSchemaItemList {
353 void **items; /* used for dynamic addition of schemata */
354 int nbItems; /* used for dynamic addition of schemata */
355 int sizeItems; /* used for dynamic addition of schemata */
356};
357
358#define XML_SCHEMA_CTXT_PARSER1 1
359#define XML_SCHEMA_CTXT_VALIDATOR2 2
360
361typedef struct _xmlSchemaAbstractCtxt xmlSchemaAbstractCtxt;
362typedef xmlSchemaAbstractCtxt *xmlSchemaAbstractCtxtPtr;
363struct _xmlSchemaAbstractCtxt {
364 int type; /* E.g. XML_SCHEMA_CTXT_VALIDATOR */
365 void *dummy; /* Fix alignment issues */
366};
367
368typedef struct _xmlSchemaBucket xmlSchemaBucket;
369typedef xmlSchemaBucket *xmlSchemaBucketPtr;
370
371#define XML_SCHEMA_SCHEMA_MAIN0 0
372#define XML_SCHEMA_SCHEMA_IMPORT1 1
373#define XML_SCHEMA_SCHEMA_INCLUDE2 2
374#define XML_SCHEMA_SCHEMA_REDEFINE3 3
375
376/**
377 * xmlSchemaSchemaRelation:
378 *
379 * Used to create a graph of schema relationships.
380 */
381typedef struct _xmlSchemaSchemaRelation xmlSchemaSchemaRelation;
382typedef xmlSchemaSchemaRelation *xmlSchemaSchemaRelationPtr;
383struct _xmlSchemaSchemaRelation {
384 xmlSchemaSchemaRelationPtr next;
385 int type; /* E.g. XML_SCHEMA_SCHEMA_IMPORT */
386 const xmlChar *importNamespace;
387 xmlSchemaBucketPtr bucket;
388};
389
390#define XML_SCHEMA_BUCKET_MARKED1<<0 1<<0
391#define XML_SCHEMA_BUCKET_COMPS_ADDED1<<1 1<<1
392
393struct _xmlSchemaBucket {
394 int type;
395 int flags;
396 const xmlChar *schemaLocation;
397 const xmlChar *origTargetNamespace;
398 const xmlChar *targetNamespace;
399 xmlDocPtr doc;
400 xmlSchemaSchemaRelationPtr relations;
401 int located;
402 int parsed;
403 int imported;
404 int preserveDoc;
405 xmlSchemaItemListPtr globals; /* Global components. */
406 xmlSchemaItemListPtr locals; /* Local components. */
407};
408
409/**
410 * xmlSchemaImport:
411 * (extends xmlSchemaBucket)
412 *
413 * Reflects a schema. Holds some information
414 * about the schema and its toplevel components. Duplicate
415 * toplevel components are not checked at this level.
416 */
417typedef struct _xmlSchemaImport xmlSchemaImport;
418typedef xmlSchemaImport *xmlSchemaImportPtr;
419struct _xmlSchemaImport {
420 int type; /* Main OR import OR include. */
421 int flags;
422 const xmlChar *schemaLocation; /* The URI of the schema document. */
423 /* For chameleon includes, @origTargetNamespace will be NULL */
424 const xmlChar *origTargetNamespace;
425 /*
426 * For chameleon includes, @targetNamespace will be the
427 * targetNamespace of the including schema.
428 */
429 const xmlChar *targetNamespace;
430 xmlDocPtr doc; /* The schema node-tree. */
431 /* @relations will hold any included/imported/redefined schemas. */
432 xmlSchemaSchemaRelationPtr relations;
433 int located;
434 int parsed;
435 int imported;
436 int preserveDoc;
437 xmlSchemaItemListPtr globals;
438 xmlSchemaItemListPtr locals;
439 /* The imported schema. */
440 xmlSchemaPtr schema;
441};
442
443/*
444* (extends xmlSchemaBucket)
445*/
446typedef struct _xmlSchemaInclude xmlSchemaInclude;
447typedef xmlSchemaInclude *xmlSchemaIncludePtr;
448struct _xmlSchemaInclude {
449 int type;
450 int flags;
451 const xmlChar *schemaLocation;
452 const xmlChar *origTargetNamespace;
453 const xmlChar *targetNamespace;
454 xmlDocPtr doc;
455 xmlSchemaSchemaRelationPtr relations;
456 int located;
457 int parsed;
458 int imported;
459 int preserveDoc;
460 xmlSchemaItemListPtr globals; /* Global components. */
461 xmlSchemaItemListPtr locals; /* Local components. */
462
463 /* The owning main or import schema bucket. */
464 xmlSchemaImportPtr ownerImport;
465};
466
467/**
468 * xmlSchemaBasicItem:
469 *
470 * The abstract base type for schema components.
471 */
472typedef struct _xmlSchemaBasicItem xmlSchemaBasicItem;
473typedef xmlSchemaBasicItem *xmlSchemaBasicItemPtr;
474struct _xmlSchemaBasicItem {
475 xmlSchemaTypeType type;
476 void *dummy; /* Fix alignment issues */
477};
478
479/**
480 * xmlSchemaAnnotItem:
481 *
482 * The abstract base type for annotated schema components.
483 * (Extends xmlSchemaBasicItem)
484 */
485typedef struct _xmlSchemaAnnotItem xmlSchemaAnnotItem;
486typedef xmlSchemaAnnotItem *xmlSchemaAnnotItemPtr;
487struct _xmlSchemaAnnotItem {
488 xmlSchemaTypeType type;
489 xmlSchemaAnnotPtr annot;
490};
491
492/**
493 * xmlSchemaTreeItem:
494 *
495 * The abstract base type for tree-like structured schema components.
496 * (Extends xmlSchemaAnnotItem)
497 */
498typedef struct _xmlSchemaTreeItem xmlSchemaTreeItem;
499typedef xmlSchemaTreeItem *xmlSchemaTreeItemPtr;
500struct _xmlSchemaTreeItem {
501 xmlSchemaTypeType type;
502 xmlSchemaAnnotPtr annot;
503 xmlSchemaTreeItemPtr next;
504 xmlSchemaTreeItemPtr children;
505};
506
507
508#define XML_SCHEMA_ATTR_USE_FIXED1<<0 1<<0
509/**
510 * xmlSchemaAttributeUsePtr:
511 *
512 * The abstract base type for tree-like structured schema components.
513 * (Extends xmlSchemaTreeItem)
514 */
515typedef struct _xmlSchemaAttributeUse xmlSchemaAttributeUse;
516typedef xmlSchemaAttributeUse *xmlSchemaAttributeUsePtr;
517struct _xmlSchemaAttributeUse {
518 xmlSchemaTypeType type;
519 xmlSchemaAnnotPtr annot;
520 xmlSchemaAttributeUsePtr next; /* The next attr. use. */
521 /*
522 * The attr. decl. OR a QName-ref. to an attr. decl. OR
523 * a QName-ref. to an attribute group definition.
524 */
525 xmlSchemaAttributePtr attrDecl;
526
527 int flags;
528 xmlNodePtr node;
529 int occurs; /* required, optional */
530 const xmlChar * defValue;
531 xmlSchemaValPtr defVal;
532};
533
534/**
535 * xmlSchemaAttributeUseProhibPtr:
536 *
537 * A helper component to reflect attribute prohibitions.
538 * (Extends xmlSchemaBasicItem)
539 */
540typedef struct _xmlSchemaAttributeUseProhib xmlSchemaAttributeUseProhib;
541typedef xmlSchemaAttributeUseProhib *xmlSchemaAttributeUseProhibPtr;
542struct _xmlSchemaAttributeUseProhib {
543 xmlSchemaTypeType type; /* == XML_SCHEMA_EXTRA_ATTR_USE_PROHIB */
544 xmlNodePtr node;
545 const xmlChar *name;
546 const xmlChar *targetNamespace;
547 int isRef;
548};
549
550/**
551 * xmlSchemaRedef:
552 */
553typedef struct _xmlSchemaRedef xmlSchemaRedef;
554typedef xmlSchemaRedef *xmlSchemaRedefPtr;
555struct _xmlSchemaRedef {
556 xmlSchemaRedefPtr next;
557 xmlSchemaBasicItemPtr item; /* The redefining component. */
558 xmlSchemaBasicItemPtr reference; /* The referencing component. */
559 xmlSchemaBasicItemPtr target; /* The to-be-redefined component. */
560 const xmlChar *refName; /* The name of the to-be-redefined component. */
561 const xmlChar *refTargetNs; /* The target namespace of the
562 to-be-redefined comp. */
563 xmlSchemaBucketPtr targetBucket; /* The redefined schema. */
564};
565
566/**
567 * xmlSchemaConstructionCtxt:
568 */
569typedef struct _xmlSchemaConstructionCtxt xmlSchemaConstructionCtxt;
570typedef xmlSchemaConstructionCtxt *xmlSchemaConstructionCtxtPtr;
571struct _xmlSchemaConstructionCtxt {
572 xmlSchemaPtr mainSchema; /* The main schema. */
573 xmlSchemaBucketPtr mainBucket; /* The main schema bucket */
574 xmlDictPtr dict;
575 xmlSchemaItemListPtr buckets; /* List of schema buckets. */
576 /* xmlSchemaItemListPtr relations; */ /* List of schema relations. */
577 xmlSchemaBucketPtr bucket; /* The current schema bucket */
578 xmlSchemaItemListPtr pending; /* All Components of all schemas that
579 need to be fixed. */
580 xmlHashTablePtr substGroups;
581 xmlSchemaRedefPtr redefs;
582 xmlSchemaRedefPtr lastRedef;
583};
584
585#define XML_SCHEMAS_PARSE_ERROR1 1
586#define SCHEMAS_PARSE_OPTIONSXML_PARSE_NOENT XML_PARSE_NOENT
587
588struct _xmlSchemaParserCtxt {
589 int type;
590 void *errCtxt; /* user specific error context */
591 xmlSchemaValidityErrorFunc error; /* the callback in case of errors */
592 xmlSchemaValidityWarningFunc warning; /* the callback in case of warning */
593 int err;
594 int nberrors;
595 xmlStructuredErrorFunc serror;
596
597 xmlSchemaConstructionCtxtPtr constructor;
598 int ownsConstructor; /* TODO: Move this to parser *flags*. */
599
600 /* xmlSchemaPtr topschema; */
601 /* xmlHashTablePtr namespaces; */
602
603 xmlSchemaPtr schema; /* The main schema in use */
604 int counter;
605
606 const xmlChar *URL;
607 xmlDocPtr doc;
608 int preserve; /* Whether the doc should be freed */
609
610 const char *buffer;
611 int size;
612
613 /*
614 * Used to build complex element content models
615 */
616 xmlAutomataPtr am;
617 xmlAutomataStatePtr start;
618 xmlAutomataStatePtr end;
619 xmlAutomataStatePtr state;
620
621 xmlDictPtr dict; /* dictionary for interned string names */
622 xmlSchemaTypePtr ctxtType; /* The current context simple/complex type */
623 int options;
624 xmlSchemaValidCtxtPtr vctxt;
625 int isS4S;
626 int isRedefine;
627 int xsiAssemble;
628 int stop; /* If the parser should stop; i.e. a critical error. */
629 const xmlChar *targetNamespace;
630 xmlSchemaBucketPtr redefined; /* The schema to be redefined. */
631
632 xmlSchemaRedefPtr redef; /* Used for redefinitions. */
633 int redefCounter; /* Used for redefinitions. */
634 xmlSchemaItemListPtr attrProhibs;
635};
636
637/**
638 * xmlSchemaQNameRef:
639 *
640 * A component reference item (not a schema component)
641 * (Extends xmlSchemaBasicItem)
642 */
643typedef struct _xmlSchemaQNameRef xmlSchemaQNameRef;
644typedef xmlSchemaQNameRef *xmlSchemaQNameRefPtr;
645struct _xmlSchemaQNameRef {
646 xmlSchemaTypeType type;
647 xmlSchemaBasicItemPtr item; /* The resolved referenced item. */
648 xmlSchemaTypeType itemType;
649 const xmlChar *name;
650 const xmlChar *targetNamespace;
651 xmlNodePtr node;
652};
653
654/**
655 * xmlSchemaParticle:
656 *
657 * A particle component.
658 * (Extends xmlSchemaTreeItem)
659 */
660typedef struct _xmlSchemaParticle xmlSchemaParticle;
661typedef xmlSchemaParticle *xmlSchemaParticlePtr;
662struct _xmlSchemaParticle {
663 xmlSchemaTypeType type;
664 xmlSchemaAnnotPtr annot;
665 xmlSchemaTreeItemPtr next; /* next particle */
666 xmlSchemaTreeItemPtr children; /* the "term" (e.g. a model group,
667 a group definition, a XML_SCHEMA_EXTRA_QNAMEREF (if a reference),
668 etc.) */
669 int minOccurs;
670 int maxOccurs;
671 xmlNodePtr node;
672};
673
674/**
675 * xmlSchemaModelGroup:
676 *
677 * A model group component.
678 * (Extends xmlSchemaTreeItem)
679 */
680typedef struct _xmlSchemaModelGroup xmlSchemaModelGroup;
681typedef xmlSchemaModelGroup *xmlSchemaModelGroupPtr;
682struct _xmlSchemaModelGroup {
683 xmlSchemaTypeType type; /* XML_SCHEMA_TYPE_SEQUENCE, XML_SCHEMA_TYPE_CHOICE, XML_SCHEMA_TYPE_ALL */
684 xmlSchemaAnnotPtr annot;
685 xmlSchemaTreeItemPtr next; /* not used */
686 xmlSchemaTreeItemPtr children; /* first particle (OR "element decl" OR "wildcard") */
687 xmlNodePtr node;
688};
689
690#define XML_SCHEMA_MODEL_GROUP_DEF_MARKED1<<0 1<<0
691#define XML_SCHEMA_MODEL_GROUP_DEF_REDEFINED1<<1 1<<1
692/**
693 * xmlSchemaModelGroupDef:
694 *
695 * A model group definition component.
696 * (Extends xmlSchemaTreeItem)
697 */
698typedef struct _xmlSchemaModelGroupDef xmlSchemaModelGroupDef;
699typedef xmlSchemaModelGroupDef *xmlSchemaModelGroupDefPtr;
700struct _xmlSchemaModelGroupDef {
701 xmlSchemaTypeType type; /* XML_SCHEMA_TYPE_GROUP */
702 xmlSchemaAnnotPtr annot;
703 xmlSchemaTreeItemPtr next; /* not used */
704 xmlSchemaTreeItemPtr children; /* the "model group" */
705 const xmlChar *name;
706 const xmlChar *targetNamespace;
707 xmlNodePtr node;
708 int flags;
709};
710
711typedef struct _xmlSchemaIDC xmlSchemaIDC;
712typedef xmlSchemaIDC *xmlSchemaIDCPtr;
713
714/**
715 * xmlSchemaIDCSelect:
716 *
717 * The identity-constraint "field" and "selector" item, holding the
718 * XPath expression.
719 */
720typedef struct _xmlSchemaIDCSelect xmlSchemaIDCSelect;
721typedef xmlSchemaIDCSelect *xmlSchemaIDCSelectPtr;
722struct _xmlSchemaIDCSelect {
723 xmlSchemaIDCSelectPtr next;
724 xmlSchemaIDCPtr idc;
725 int index; /* an index position if significant for IDC key-sequences */
726 const xmlChar *xpath; /* the XPath expression */
727 void *xpathComp; /* the compiled XPath expression */
728};
729
730/**
731 * xmlSchemaIDC:
732 *
733 * The identity-constraint definition component.
734 * (Extends xmlSchemaAnnotItem)
735 */
736
737struct _xmlSchemaIDC {
738 xmlSchemaTypeType type;
739 xmlSchemaAnnotPtr annot;
740 xmlSchemaIDCPtr next;
741 xmlNodePtr node;
742 const xmlChar *name;
743 const xmlChar *targetNamespace;
744 xmlSchemaIDCSelectPtr selector;
745 xmlSchemaIDCSelectPtr fields;
746 int nbFields;
747 xmlSchemaQNameRefPtr ref;
748};
749
750/**
751 * xmlSchemaIDCAug:
752 *
753 * The augmented IDC information used for validation.
754 */
755typedef struct _xmlSchemaIDCAug xmlSchemaIDCAug;
756typedef xmlSchemaIDCAug *xmlSchemaIDCAugPtr;
757struct _xmlSchemaIDCAug {
758 xmlSchemaIDCAugPtr next; /* next in a list */
759 xmlSchemaIDCPtr def; /* the IDC definition */
760 int keyrefDepth; /* the lowest tree level to which IDC
761 tables need to be bubbled upwards */
762};
763
764/**
765 * xmlSchemaPSVIIDCKeySequence:
766 *
767 * The key sequence of a node table item.
768 */
769typedef struct _xmlSchemaPSVIIDCKey xmlSchemaPSVIIDCKey;
770typedef xmlSchemaPSVIIDCKey *xmlSchemaPSVIIDCKeyPtr;
771struct _xmlSchemaPSVIIDCKey {
772 xmlSchemaTypePtr type;
773 xmlSchemaValPtr val;
774};
775
776/**
777 * xmlSchemaPSVIIDCNode:
778 *
779 * The node table item of a node table.
780 */
781typedef struct _xmlSchemaPSVIIDCNode xmlSchemaPSVIIDCNode;
782typedef xmlSchemaPSVIIDCNode *xmlSchemaPSVIIDCNodePtr;
783struct _xmlSchemaPSVIIDCNode {
784 xmlNodePtr node;
785 xmlSchemaPSVIIDCKeyPtr *keys;
786 int nodeLine;
787 int nodeQNameID;
788
789};
790
791/**
792 * xmlSchemaPSVIIDCBinding:
793 *
794 * The identity-constraint binding item of the [identity-constraint table].
795 */
796typedef struct _xmlSchemaPSVIIDCBinding xmlSchemaPSVIIDCBinding;
797typedef xmlSchemaPSVIIDCBinding *xmlSchemaPSVIIDCBindingPtr;
798struct _xmlSchemaPSVIIDCBinding {
799 xmlSchemaPSVIIDCBindingPtr next; /* next binding of a specific node */
800 xmlSchemaIDCPtr definition; /* the IDC definition */
801 xmlSchemaPSVIIDCNodePtr *nodeTable; /* array of key-sequences */
802 int nbNodes; /* number of entries in the node table */
803 int sizeNodes; /* size of the node table */
804 xmlSchemaItemListPtr dupls;
805};
806
807
808#define XPATH_STATE_OBJ_TYPE_IDC_SELECTOR1 1
809#define XPATH_STATE_OBJ_TYPE_IDC_FIELD2 2
810
811#define XPATH_STATE_OBJ_MATCHES-2 -2
812#define XPATH_STATE_OBJ_BLOCKED-3 -3
813
814typedef struct _xmlSchemaIDCMatcher xmlSchemaIDCMatcher;
815typedef xmlSchemaIDCMatcher *xmlSchemaIDCMatcherPtr;
816
817/**
818 * xmlSchemaIDCStateObj:
819 *
820 * The state object used to evaluate XPath expressions.
821 */
822typedef struct _xmlSchemaIDCStateObj xmlSchemaIDCStateObj;
823typedef xmlSchemaIDCStateObj *xmlSchemaIDCStateObjPtr;
824struct _xmlSchemaIDCStateObj {
825 int type;
826 xmlSchemaIDCStateObjPtr next; /* next if in a list */
827 int depth; /* depth of creation */
828 int *history; /* list of (depth, state-id) tuples */
829 int nbHistory;
830 int sizeHistory;
831 xmlSchemaIDCMatcherPtr matcher; /* the correspondent field/selector
832 matcher */
833 xmlSchemaIDCSelectPtr sel;
834 void *xpathCtxt;
835};
836
837#define IDC_MATCHER0 0
838
839/**
840 * xmlSchemaIDCMatcher:
841 *
842 * Used to evaluate IDC selectors (and fields).
843 */
844struct _xmlSchemaIDCMatcher {
845 int type;
846 int depth; /* the tree depth at creation time */
847 xmlSchemaIDCMatcherPtr next; /* next in the list */
848 xmlSchemaIDCMatcherPtr nextCached; /* next in the cache list */
849 xmlSchemaIDCAugPtr aidc; /* the augmented IDC item */
850 int idcType;
851 xmlSchemaPSVIIDCKeyPtr **keySeqs; /* the key-sequences of the target
852 elements */
853 int sizeKeySeqs;
854 xmlSchemaItemListPtr targets; /* list of target-node
855 (xmlSchemaPSVIIDCNodePtr) entries */
856 xmlHashTablePtr htab;
857};
858
859/*
860* Element info flags.
861*/
862#define XML_SCHEMA_NODE_INFO_FLAG_OWNED_NAMES1<<0 1<<0
863#define XML_SCHEMA_NODE_INFO_FLAG_OWNED_VALUES1<<1 1<<1
864#define XML_SCHEMA_ELEM_INFO_NILLED1<<2 1<<2
865#define XML_SCHEMA_ELEM_INFO_LOCAL_TYPE1<<3 1<<3
866
867#define XML_SCHEMA_NODE_INFO_VALUE_NEEDED1<<4 1<<4
868#define XML_SCHEMA_ELEM_INFO_EMPTY1<<5 1<<5
869#define XML_SCHEMA_ELEM_INFO_HAS_CONTENT1<<6 1<<6
870
871#define XML_SCHEMA_ELEM_INFO_HAS_ELEM_CONTENT1<<7 1<<7
872#define XML_SCHEMA_ELEM_INFO_ERR_BAD_CONTENT1<<8 1<<8
873#define XML_SCHEMA_NODE_INFO_ERR_NOT_EXPECTED1<<9 1<<9
874#define XML_SCHEMA_NODE_INFO_ERR_BAD_TYPE1<<10 1<<10
875
876/**
877 * xmlSchemaNodeInfo:
878 *
879 * Holds information of an element node.
880 */
881struct _xmlSchemaNodeInfo {
882 int nodeType;
883 xmlNodePtr node;
884 int nodeLine;
885 const xmlChar *localName;
886 const xmlChar *nsName;
887 const xmlChar *value;
888 xmlSchemaValPtr val; /* the pre-computed value if any */
889 xmlSchemaTypePtr typeDef; /* the complex/simple type definition if any */
890
891 int flags; /* combination of node info flags */
892
893 int valNeeded;
894 int normVal;
895
896 xmlSchemaElementPtr decl; /* the element/attribute declaration */
897 int depth;
898 xmlSchemaPSVIIDCBindingPtr idcTable; /* the table of PSVI IDC bindings
899 for the scope element*/
900 xmlSchemaIDCMatcherPtr idcMatchers; /* the IDC matchers for the scope
901 element */
902 xmlRegExecCtxtPtr regexCtxt;
903
904 const xmlChar **nsBindings; /* Namespace bindings on this element */
905 int nbNsBindings;
906 int sizeNsBindings;
907
908 int hasKeyrefs;
909 int appliedXPath; /* Indicates that an XPath has been applied. */
910};
911
912#define XML_SCHEMAS_ATTR_UNKNOWN1 1
913#define XML_SCHEMAS_ATTR_ASSESSED2 2
914#define XML_SCHEMAS_ATTR_PROHIBITED3 3
915#define XML_SCHEMAS_ATTR_ERR_MISSING4 4
916#define XML_SCHEMAS_ATTR_INVALID_VALUE5 5
917#define XML_SCHEMAS_ATTR_ERR_NO_TYPE6 6
918#define XML_SCHEMAS_ATTR_ERR_FIXED_VALUE7 7
919#define XML_SCHEMAS_ATTR_DEFAULT8 8
920#define XML_SCHEMAS_ATTR_VALIDATE_VALUE9 9
921#define XML_SCHEMAS_ATTR_ERR_WILD_STRICT_NO_DECL10 10
922#define XML_SCHEMAS_ATTR_HAS_ATTR_USE11 11
923#define XML_SCHEMAS_ATTR_HAS_ATTR_DECL12 12
924#define XML_SCHEMAS_ATTR_WILD_SKIP13 13
925#define XML_SCHEMAS_ATTR_WILD_LAX_NO_DECL14 14
926#define XML_SCHEMAS_ATTR_ERR_WILD_DUPLICATE_ID15 15
927#define XML_SCHEMAS_ATTR_ERR_WILD_AND_USE_ID16 16
928#define XML_SCHEMAS_ATTR_META17 17
929/*
930* @metaType values of xmlSchemaAttrInfo.
931*/
932#define XML_SCHEMA_ATTR_INFO_META_XSI_TYPE1 1
933#define XML_SCHEMA_ATTR_INFO_META_XSI_NIL2 2
934#define XML_SCHEMA_ATTR_INFO_META_XSI_SCHEMA_LOC3 3
935#define XML_SCHEMA_ATTR_INFO_META_XSI_NO_NS_SCHEMA_LOC4 4
936#define XML_SCHEMA_ATTR_INFO_META_XMLNS5 5
937
938typedef struct _xmlSchemaAttrInfo xmlSchemaAttrInfo;
939typedef xmlSchemaAttrInfo *xmlSchemaAttrInfoPtr;
940struct _xmlSchemaAttrInfo {
941 int nodeType;
942 xmlNodePtr node;
943 int nodeLine;
944 const xmlChar *localName;
945 const xmlChar *nsName;
946 const xmlChar *value;
947 xmlSchemaValPtr val; /* the pre-computed value if any */
948 xmlSchemaTypePtr typeDef; /* the complex/simple type definition if any */
949 int flags; /* combination of node info flags */
950
951 xmlSchemaAttributePtr decl; /* the attribute declaration */
952 xmlSchemaAttributeUsePtr use; /* the attribute use */
953 int state;
954 int metaType;
955 const xmlChar *vcValue; /* the value constraint value */
956 xmlSchemaNodeInfoPtr parent;
957};
958
959
960#define XML_SCHEMA_VALID_CTXT_FLAG_STREAM1 1
961/**
962 * xmlSchemaValidCtxt:
963 *
964 * A Schemas validation context
965 */
966struct _xmlSchemaValidCtxt {
967 int type;
968 void *errCtxt; /* user specific data block */
969 xmlSchemaValidityErrorFunc error; /* the callback in case of errors */
970 xmlSchemaValidityWarningFunc warning; /* the callback in case of warning */
971 xmlStructuredErrorFunc serror;
972
973 xmlSchemaPtr schema; /* The schema in use */
974 xmlDocPtr doc;
975 xmlParserInputBufferPtr input;
976 xmlCharEncoding enc;
977 xmlSAXHandlerPtr sax;
978 xmlParserCtxtPtr parserCtxt;
979 void *user_data; /* TODO: What is this for? */
980 char *filename;
981
982 int err;
983 int nberrors;
984
985 xmlNodePtr node;
986 xmlNodePtr cur;
987 /* xmlSchemaTypePtr type; */
988
989 xmlRegExecCtxtPtr regexp;
990 xmlSchemaValPtr value;
991
992 int valueWS;
993 int options;
994 xmlNodePtr validationRoot;
995 xmlSchemaParserCtxtPtr pctxt;
996 int xsiAssemble;
997
998 int depth;
999 xmlSchemaNodeInfoPtr *elemInfos; /* array of element information */
1000 int sizeElemInfos;
1001 xmlSchemaNodeInfoPtr inode; /* the current element information */
1002
1003 xmlSchemaIDCAugPtr aidcs; /* a list of augmented IDC information */
1004
1005 xmlSchemaIDCStateObjPtr xpathStates; /* first active state object. */
1006 xmlSchemaIDCStateObjPtr xpathStatePool; /* first stored state object. */
1007 xmlSchemaIDCMatcherPtr idcMatcherCache; /* Cache for IDC matcher objects. */
1008
1009 xmlSchemaPSVIIDCNodePtr *idcNodes; /* list of all IDC node-table entries*/
1010 int nbIdcNodes;
1011 int sizeIdcNodes;
1012
1013 xmlSchemaPSVIIDCKeyPtr *idcKeys; /* list of all IDC node-table entries */
1014 int nbIdcKeys;
1015 int sizeIdcKeys;
1016
1017 int flags;
1018
1019 xmlDictPtr dict;
1020
1021#ifdef LIBXML_READER_ENABLED
1022 xmlTextReaderPtr reader;
1023#endif
1024
1025 xmlSchemaAttrInfoPtr *attrInfos;
1026 int nbAttrInfos;
1027 int sizeAttrInfos;
1028
1029 int skipDepth;
1030 xmlSchemaItemListPtr nodeQNames;
1031 int hasKeyrefs;
1032 int createIDCNodeTables;
1033 int psviExposeIDCNodeTables;
1034
1035 /* Locator for error reporting in streaming mode */
1036 xmlSchemaValidityLocatorFunc locFunc;
1037 void *locCtxt;
1038};
1039
1040/**
1041 * xmlSchemaSubstGroup:
1042 *
1043 *
1044 */
1045typedef struct _xmlSchemaSubstGroup xmlSchemaSubstGroup;
1046typedef xmlSchemaSubstGroup *xmlSchemaSubstGroupPtr;
1047struct _xmlSchemaSubstGroup {
1048 xmlSchemaElementPtr head;
1049 xmlSchemaItemListPtr members;
1050};
1051
1052/**
1053 * xmlIDCHashEntry:
1054 *
1055 * an entry in hash tables to quickly look up keys/uniques
1056 */
1057typedef struct _xmlIDCHashEntry xmlIDCHashEntry;
1058typedef xmlIDCHashEntry *xmlIDCHashEntryPtr;
1059struct _xmlIDCHashEntry {
1060 xmlIDCHashEntryPtr next; /* next item with same hash */
1061 int index; /* index into associated item list */
1062};
1063
1064/************************************************************************
1065 * *
1066 * Some predeclarations *
1067 * *
1068 ************************************************************************/
1069
1070static int xmlSchemaParseInclude(xmlSchemaParserCtxtPtr ctxt,
1071 xmlSchemaPtr schema,
1072 xmlNodePtr node);
1073static int xmlSchemaParseRedefine(xmlSchemaParserCtxtPtr ctxt,
1074 xmlSchemaPtr schema,
1075 xmlNodePtr node);
1076static int
1077xmlSchemaTypeFixup(xmlSchemaTypePtr type,
1078 xmlSchemaAbstractCtxtPtr ctxt);
1079static const xmlChar *
1080xmlSchemaFacetTypeToString(xmlSchemaTypeType type);
1081static int
1082xmlSchemaParseImport(xmlSchemaParserCtxtPtr ctxt, xmlSchemaPtr schema,
1083 xmlNodePtr node);
1084static int
1085xmlSchemaCheckFacetValues(xmlSchemaTypePtr typeDecl,
1086 xmlSchemaParserCtxtPtr ctxt);
1087static void
1088xmlSchemaClearValidCtxt(xmlSchemaValidCtxtPtr vctxt);
1089static xmlSchemaWhitespaceValueType
1090xmlSchemaGetWhiteSpaceFacetValue(xmlSchemaTypePtr type);
1091static xmlSchemaTreeItemPtr
1092xmlSchemaParseModelGroup(xmlSchemaParserCtxtPtr ctxt, xmlSchemaPtr schema,
1093 xmlNodePtr node, xmlSchemaTypeType type,
1094 int withParticle);
1095static const xmlChar *
1096xmlSchemaGetComponentTypeStr(xmlSchemaBasicItemPtr item);
1097static xmlSchemaTypeLinkPtr
1098xmlSchemaGetUnionSimpleTypeMemberTypes(xmlSchemaTypePtr type);
1099static void
1100xmlSchemaInternalErr(xmlSchemaAbstractCtxtPtr actxt,
1101 const char *funcName,
1102 const char *message) LIBXML_ATTR_FORMAT(3,0)__attribute__((__format__(__printf__,3,0)));
1103static int
1104xmlSchemaCheckCOSSTDerivedOK(xmlSchemaAbstractCtxtPtr ctxt,
1105 xmlSchemaTypePtr type,
1106 xmlSchemaTypePtr baseType,
1107 int subset);
1108static void
1109xmlSchemaCheckElementDeclComponent(xmlSchemaElementPtr elemDecl,
1110 xmlSchemaParserCtxtPtr ctxt);
1111static void
1112xmlSchemaComponentListFree(xmlSchemaItemListPtr list);
1113static xmlSchemaQNameRefPtr
1114xmlSchemaParseAttributeGroupRef(xmlSchemaParserCtxtPtr pctxt,
1115 xmlSchemaPtr schema,
1116 xmlNodePtr node);
1117
1118/************************************************************************
1119 * *
1120 * Helper functions *
1121 * *
1122 ************************************************************************/
1123
1124/**
1125 * xmlSchemaItemTypeToStr:
1126 * @type: the type of the schema item
1127 *
1128 * Returns the component name of a schema item.
1129 */
1130static const xmlChar *
1131xmlSchemaItemTypeToStr(xmlSchemaTypeType type)
1132{
1133 switch (type) {
1134 case XML_SCHEMA_TYPE_BASIC:
1135 return(BAD_CAST(xmlChar *) "simple type definition");
1136 case XML_SCHEMA_TYPE_SIMPLE:
1137 return(BAD_CAST(xmlChar *) "simple type definition");
1138 case XML_SCHEMA_TYPE_COMPLEX:
1139 return(BAD_CAST(xmlChar *) "complex type definition");
1140 case XML_SCHEMA_TYPE_ELEMENT:
1141 return(BAD_CAST(xmlChar *) "element declaration");
1142 case XML_SCHEMA_TYPE_ATTRIBUTE_USE:
1143 return(BAD_CAST(xmlChar *) "attribute use");
1144 case XML_SCHEMA_TYPE_ATTRIBUTE:
1145 return(BAD_CAST(xmlChar *) "attribute declaration");
1146 case XML_SCHEMA_TYPE_GROUP:
1147 return(BAD_CAST(xmlChar *) "model group definition");
1148 case XML_SCHEMA_TYPE_ATTRIBUTEGROUP:
1149 return(BAD_CAST(xmlChar *) "attribute group definition");
1150 case XML_SCHEMA_TYPE_NOTATION:
1151 return(BAD_CAST(xmlChar *) "notation declaration");
1152 case XML_SCHEMA_TYPE_SEQUENCE:
1153 return(BAD_CAST(xmlChar *) "model group (sequence)");
1154 case XML_SCHEMA_TYPE_CHOICE:
1155 return(BAD_CAST(xmlChar *) "model group (choice)");
1156 case XML_SCHEMA_TYPE_ALL:
1157 return(BAD_CAST(xmlChar *) "model group (all)");
1158 case XML_SCHEMA_TYPE_PARTICLE:
1159 return(BAD_CAST(xmlChar *) "particle");
1160 case XML_SCHEMA_TYPE_IDC_UNIQUE:
1161 return(BAD_CAST(xmlChar *) "unique identity-constraint");
1162 /* return(BAD_CAST "IDC (unique)"); */
1163 case XML_SCHEMA_TYPE_IDC_KEY:
1164 return(BAD_CAST(xmlChar *) "key identity-constraint");
1165 /* return(BAD_CAST "IDC (key)"); */
1166 case XML_SCHEMA_TYPE_IDC_KEYREF:
1167 return(BAD_CAST(xmlChar *) "keyref identity-constraint");
1168 /* return(BAD_CAST "IDC (keyref)"); */
1169 case XML_SCHEMA_TYPE_ANY:
1170 return(BAD_CAST(xmlChar *) "wildcard (any)");
1171 case XML_SCHEMA_EXTRA_QNAMEREF:
1172 return(BAD_CAST(xmlChar *) "[helper component] QName reference");
1173 case XML_SCHEMA_EXTRA_ATTR_USE_PROHIB:
1174 return(BAD_CAST(xmlChar *) "[helper component] attribute use prohibition");
1175 default:
1176 return(BAD_CAST(xmlChar *) "Not a schema component");
1177 }
1178}
1179
1180/**
1181 * xmlSchemaGetComponentTypeStr:
1182 * @type: the type of the schema item
1183 *
1184 * Returns the component name of a schema item.
1185 */
1186static const xmlChar *
1187xmlSchemaGetComponentTypeStr(xmlSchemaBasicItemPtr item)
1188{
1189 switch (item->type) {
1190 case XML_SCHEMA_TYPE_BASIC:
1191 if (WXS_IS_COMPLEX(WXS_TYPE_CAST item)((((xmlSchemaTypePtr) item)->type == XML_SCHEMA_TYPE_COMPLEX
) || (((xmlSchemaTypePtr) item)->builtInType == XML_SCHEMAS_ANYTYPE
))
)
1192 return(BAD_CAST(xmlChar *) "complex type definition");
1193 else
1194 return(BAD_CAST(xmlChar *) "simple type definition");
1195 default:
1196 return(xmlSchemaItemTypeToStr(item->type));
1197 }
1198}
1199
1200/**
1201 * xmlSchemaGetComponentNode:
1202 * @item: a schema component
1203 *
1204 * Returns node associated with the schema component.
1205 * NOTE that such a node need not be available; plus, a component's
1206 * node need not to reflect the component directly, since there is no
1207 * one-to-one relationship between the XML Schema representation and
1208 * the component representation.
1209 */
1210static xmlNodePtr
1211xmlSchemaGetComponentNode(xmlSchemaBasicItemPtr item)
1212{
1213 switch (item->type) {
1214 case XML_SCHEMA_TYPE_ELEMENT:
1215 return (((xmlSchemaElementPtr) item)->node);
1216 case XML_SCHEMA_TYPE_ATTRIBUTE:
1217 return (((xmlSchemaAttributePtr) item)->node);
1218 case XML_SCHEMA_TYPE_COMPLEX:
1219 case XML_SCHEMA_TYPE_SIMPLE:
1220 return (((xmlSchemaTypePtr) item)->node);
1221 case XML_SCHEMA_TYPE_ANY:
1222 case XML_SCHEMA_TYPE_ANY_ATTRIBUTE:
1223 return (((xmlSchemaWildcardPtr) item)->node);
1224 case XML_SCHEMA_TYPE_PARTICLE:
1225 return (((xmlSchemaParticlePtr) item)->node);
1226 case XML_SCHEMA_TYPE_SEQUENCE:
1227 case XML_SCHEMA_TYPE_CHOICE:
1228 case XML_SCHEMA_TYPE_ALL:
1229 return (((xmlSchemaModelGroupPtr) item)->node);
1230 case XML_SCHEMA_TYPE_GROUP:
1231 return (((xmlSchemaModelGroupDefPtr) item)->node);
1232 case XML_SCHEMA_TYPE_ATTRIBUTEGROUP:
1233 return (((xmlSchemaAttributeGroupPtr) item)->node);
1234 case XML_SCHEMA_TYPE_IDC_UNIQUE:
1235 case XML_SCHEMA_TYPE_IDC_KEY:
1236 case XML_SCHEMA_TYPE_IDC_KEYREF:
1237 return (((xmlSchemaIDCPtr) item)->node);
1238 case XML_SCHEMA_EXTRA_QNAMEREF:
1239 return(((xmlSchemaQNameRefPtr) item)->node);
1240 /* TODO: What to do with NOTATIONs?
1241 case XML_SCHEMA_TYPE_NOTATION:
1242 return (((xmlSchemaNotationPtr) item)->node);
1243 */
1244 case XML_SCHEMA_TYPE_ATTRIBUTE_USE:
1245 return (((xmlSchemaAttributeUsePtr) item)->node);
1246 default:
1247 return (NULL((void*)0));
1248 }
1249}
1250
1251#if 0
1252/**
1253 * xmlSchemaGetNextComponent:
1254 * @item: a schema component
1255 *
1256 * Returns the next sibling of the schema component.
1257 */
1258static xmlSchemaBasicItemPtr
1259xmlSchemaGetNextComponent(xmlSchemaBasicItemPtr item)
1260{
1261 switch (item->type) {
1262 case XML_SCHEMA_TYPE_ELEMENT:
1263 return ((xmlSchemaBasicItemPtr) ((xmlSchemaElementPtr) item)->next);
1264 case XML_SCHEMA_TYPE_ATTRIBUTE:
1265 return ((xmlSchemaBasicItemPtr) ((xmlSchemaAttributePtr) item)->next);
1266 case XML_SCHEMA_TYPE_COMPLEX:
1267 case XML_SCHEMA_TYPE_SIMPLE:
1268 return ((xmlSchemaBasicItemPtr) ((xmlSchemaTypePtr) item)->next);
1269 case XML_SCHEMA_TYPE_ANY:
1270 case XML_SCHEMA_TYPE_ANY_ATTRIBUTE:
1271 return (NULL((void*)0));
1272 case XML_SCHEMA_TYPE_PARTICLE:
1273 return ((xmlSchemaBasicItemPtr) ((xmlSchemaParticlePtr) item)->next);
1274 case XML_SCHEMA_TYPE_SEQUENCE:
1275 case XML_SCHEMA_TYPE_CHOICE:
1276 case XML_SCHEMA_TYPE_ALL:
1277 return (NULL((void*)0));
1278 case XML_SCHEMA_TYPE_GROUP:
1279 return (NULL((void*)0));
1280 case XML_SCHEMA_TYPE_ATTRIBUTEGROUP:
1281 return ((xmlSchemaBasicItemPtr) ((xmlSchemaAttributeGroupPtr) item)->next);
1282 case XML_SCHEMA_TYPE_IDC_UNIQUE:
1283 case XML_SCHEMA_TYPE_IDC_KEY:
1284 case XML_SCHEMA_TYPE_IDC_KEYREF:
1285 return ((xmlSchemaBasicItemPtr) ((xmlSchemaIDCPtr) item)->next);
1286 default:
1287 return (NULL((void*)0));
1288 }
1289}
1290#endif
1291
1292
1293/**
1294 * xmlSchemaFormatQName:
1295 * @buf: the string buffer
1296 * @namespaceName: the namespace name
1297 * @localName: the local name
1298 *
1299 * Returns the given QName in the format "{namespaceName}localName" or
1300 * just "localName" if @namespaceName is NULL.
1301 *
1302 * Returns the localName if @namespaceName is NULL, a formatted
1303 * string otherwise.
1304 */
1305static const xmlChar*
1306xmlSchemaFormatQName(xmlChar **buf,
1307 const xmlChar *namespaceName,
1308 const xmlChar *localName)
1309{
1310 FREE_AND_NULL(*buf)if ((*buf) != ((void*)0)) { xmlFree((xmlChar *) (*buf)); *buf
= ((void*)0); }
1311 if (namespaceName != NULL((void*)0)) {
1312 *buf = xmlStrdup(BAD_CAST(xmlChar *) "{");
1313 *buf = xmlStrcat(*buf, namespaceName);
1314 *buf = xmlStrcat(*buf, BAD_CAST(xmlChar *) "}");
1315 }
1316 if (localName != NULL((void*)0)) {
1317 if (namespaceName == NULL((void*)0))
1318 return(localName);
1319 *buf = xmlStrcat(*buf, localName);
1320 } else {
1321 *buf = xmlStrcat(*buf, BAD_CAST(xmlChar *) "(NULL)");
1322 }
1323 return ((const xmlChar *) *buf);
1324}
1325
1326static const xmlChar*
1327xmlSchemaFormatQNameNs(xmlChar **buf, xmlNsPtr ns, const xmlChar *localName)
1328{
1329 if (ns != NULL((void*)0))
1330 return (xmlSchemaFormatQName(buf, ns->href, localName));
1331 else
1332 return (xmlSchemaFormatQName(buf, NULL((void*)0), localName));
1333}
1334
1335static const xmlChar *
1336xmlSchemaGetComponentName(xmlSchemaBasicItemPtr item)
1337{
1338 if (item == NULL((void*)0)) {
1339 return (NULL((void*)0));
1340 }
1341 switch (item->type) {
1342 case XML_SCHEMA_TYPE_ELEMENT:
1343 return (((xmlSchemaElementPtr) item)->name);
1344 case XML_SCHEMA_TYPE_ATTRIBUTE:
1345 return (((xmlSchemaAttributePtr) item)->name);
1346 case XML_SCHEMA_TYPE_ATTRIBUTEGROUP:
1347 return (((xmlSchemaAttributeGroupPtr) item)->name);
1348 case XML_SCHEMA_TYPE_BASIC:
1349 case XML_SCHEMA_TYPE_SIMPLE:
1350 case XML_SCHEMA_TYPE_COMPLEX:
1351 return (((xmlSchemaTypePtr) item)->name);
1352 case XML_SCHEMA_TYPE_GROUP:
1353 return (((xmlSchemaModelGroupDefPtr) item)->name);
1354 case XML_SCHEMA_TYPE_IDC_KEY:
1355 case XML_SCHEMA_TYPE_IDC_UNIQUE:
1356 case XML_SCHEMA_TYPE_IDC_KEYREF:
1357 return (((xmlSchemaIDCPtr) item)->name);
1358 case XML_SCHEMA_TYPE_ATTRIBUTE_USE:
1359 if (WXS_ATTRUSE_DECL(item)((xmlSchemaAttributeUsePtr) (item))->attrDecl != NULL((void*)0)) {
1360 return(xmlSchemaGetComponentName(
1361 WXS_BASIC_CAST(xmlSchemaBasicItemPtr) WXS_ATTRUSE_DECL(item)((xmlSchemaAttributeUsePtr) (item))->attrDecl));
1362 } else
1363 return(NULL((void*)0));
1364 case XML_SCHEMA_EXTRA_QNAMEREF:
1365 return (((xmlSchemaQNameRefPtr) item)->name);
1366 case XML_SCHEMA_TYPE_NOTATION:
1367 return (((xmlSchemaNotationPtr) item)->name);
1368 default:
1369 /*
1370 * Other components cannot have names.
1371 */
1372 break;
1373 }
1374 return (NULL((void*)0));
1375}
1376
1377#define xmlSchemaGetQNameRefName(r)((xmlSchemaQNameRefPtr) (r))->name (WXS_QNAME_CAST(xmlSchemaQNameRefPtr) (r))->name
1378#define xmlSchemaGetQNameRefTargetNs(r)((xmlSchemaQNameRefPtr) (r))->targetNamespace (WXS_QNAME_CAST(xmlSchemaQNameRefPtr) (r))->targetNamespace
1379/*
1380static const xmlChar *
1381xmlSchemaGetQNameRefName(void *ref)
1382{
1383 return(((xmlSchemaQNameRefPtr) ref)->name);
1384}
1385
1386static const xmlChar *
1387xmlSchemaGetQNameRefTargetNs(void *ref)
1388{
1389 return(((xmlSchemaQNameRefPtr) ref)->targetNamespace);
1390}
1391*/
1392
1393static const xmlChar *
1394xmlSchemaGetComponentTargetNs(xmlSchemaBasicItemPtr item)
1395{
1396 if (item == NULL((void*)0)) {
1397 return (NULL((void*)0));
1398 }
1399 switch (item->type) {
1400 case XML_SCHEMA_TYPE_ELEMENT:
1401 return (((xmlSchemaElementPtr) item)->targetNamespace);
1402 case XML_SCHEMA_TYPE_ATTRIBUTE:
1403 return (((xmlSchemaAttributePtr) item)->targetNamespace);
1404 case XML_SCHEMA_TYPE_ATTRIBUTEGROUP:
1405 return (((xmlSchemaAttributeGroupPtr) item)->targetNamespace);
1406 case XML_SCHEMA_TYPE_BASIC:
1407 return (BAD_CAST(xmlChar *) "http://www.w3.org/2001/XMLSchema");
1408 case XML_SCHEMA_TYPE_SIMPLE:
1409 case XML_SCHEMA_TYPE_COMPLEX:
1410 return (((xmlSchemaTypePtr) item)->targetNamespace);
1411 case XML_SCHEMA_TYPE_GROUP:
1412 return (((xmlSchemaModelGroupDefPtr) item)->targetNamespace);
1413 case XML_SCHEMA_TYPE_IDC_KEY:
1414 case XML_SCHEMA_TYPE_IDC_UNIQUE:
1415 case XML_SCHEMA_TYPE_IDC_KEYREF:
1416 return (((xmlSchemaIDCPtr) item)->targetNamespace);
1417 case XML_SCHEMA_TYPE_ATTRIBUTE_USE:
1418 if (WXS_ATTRUSE_DECL(item)((xmlSchemaAttributeUsePtr) (item))->attrDecl != NULL((void*)0)) {
1419 return(xmlSchemaGetComponentTargetNs(
1420 WXS_BASIC_CAST(xmlSchemaBasicItemPtr) WXS_ATTRUSE_DECL(item)((xmlSchemaAttributeUsePtr) (item))->attrDecl));
1421 }
1422 /* TODO: Will returning NULL break something? */
1423 break;
1424 case XML_SCHEMA_EXTRA_QNAMEREF:
1425 return (((xmlSchemaQNameRefPtr) item)->targetNamespace);
1426 case XML_SCHEMA_TYPE_NOTATION:
1427 return (((xmlSchemaNotationPtr) item)->targetNamespace);
1428 default:
1429 /*
1430 * Other components cannot have names.
1431 */
1432 break;
1433 }
1434 return (NULL((void*)0));
1435}
1436
1437static const xmlChar*
1438xmlSchemaGetComponentQName(xmlChar **buf,
1439 void *item)
1440{
1441 return (xmlSchemaFormatQName(buf,
1442 xmlSchemaGetComponentTargetNs((xmlSchemaBasicItemPtr) item),
1443 xmlSchemaGetComponentName((xmlSchemaBasicItemPtr) item)));
1444}
1445
1446static const xmlChar*
1447xmlSchemaGetComponentDesignation(xmlChar **buf, void *item)
1448{
1449 xmlChar *str = NULL((void*)0);
1450
1451 *buf = xmlStrcat(*buf, WXS_ITEM_TYPE_NAME(item)xmlSchemaGetComponentTypeStr((xmlSchemaBasicItemPtr) (item)));
1452 *buf = xmlStrcat(*buf, BAD_CAST(xmlChar *) " '");
1453 *buf = xmlStrcat(*buf, xmlSchemaGetComponentQName(&str,
1454 (xmlSchemaBasicItemPtr) item));
1455 *buf = xmlStrcat(*buf, BAD_CAST(xmlChar *) "'");
1456 FREE_AND_NULL(str)if ((str) != ((void*)0)) { xmlFree((xmlChar *) (str)); str = (
(void*)0); }
;
1457 return(*buf);
1458}
1459
1460static const xmlChar*
1461xmlSchemaGetIDCDesignation(xmlChar **buf, xmlSchemaIDCPtr idc)
1462{
1463 return(xmlSchemaGetComponentDesignation(buf, idc));
1464}
1465
1466/**
1467 * xmlSchemaWildcardPCToString:
1468 * @pc: the type of processContents
1469 *
1470 * Returns a string representation of the type of
1471 * processContents.
1472 */
1473static const xmlChar *
1474xmlSchemaWildcardPCToString(int pc)
1475{
1476 switch (pc) {
1477 case XML_SCHEMAS_ANY_SKIP1:
1478 return (BAD_CAST(xmlChar *) "skip");
1479 case XML_SCHEMAS_ANY_LAX2:
1480 return (BAD_CAST(xmlChar *) "lax");
1481 case XML_SCHEMAS_ANY_STRICT3:
1482 return (BAD_CAST(xmlChar *) "strict");
1483 default:
1484 return (BAD_CAST(xmlChar *) "invalid process contents");
1485 }
1486}
1487
1488/**
1489 * xmlSchemaGetCanonValueWhtspExt:
1490 * @val: the precomputed value
1491 * @retValue: the returned value
1492 * @ws: the whitespace type of the value
1493 * @for_hash: non-zero if this is supposed to generate a string for hashing
1494 *
1495 * Get a the canonical representation of the value.
1496 * The caller has to free the returned retValue.
1497 *
1498 * Returns 0 if the value could be built and -1 in case of
1499 * API errors or if the value type is not supported yet.
1500 */
1501static int
1502xmlSchemaGetCanonValueWhtspExt_1(xmlSchemaValPtr val,
1503 xmlSchemaWhitespaceValueType ws,
1504 xmlChar **retValue,
1505 int for_hash)
1506{
1507 int list;
1508 xmlSchemaValType valType;
1509 const xmlChar *value, *value2 = NULL((void*)0);
1510
1511
1512 if ((retValue == NULL((void*)0)) || (val == NULL((void*)0)))
1513 return (-1);
1514 list = xmlSchemaValueGetNext(val) ? 1 : 0;
1515 *retValue = NULL((void*)0);
1516 do {
1517 value = NULL((void*)0);
1518 valType = xmlSchemaGetValType(val);
1519 switch (valType) {
1520 case XML_SCHEMAS_STRING:
1521 case XML_SCHEMAS_NORMSTRING:
1522 case XML_SCHEMAS_ANYSIMPLETYPE:
1523 value = xmlSchemaValueGetAsString(val);
1524 if (value != NULL((void*)0)) {
1525 if (ws == XML_SCHEMA_WHITESPACE_COLLAPSE)
1526 value2 = xmlSchemaCollapseString(value);
1527 else if (ws == XML_SCHEMA_WHITESPACE_REPLACE)
1528 value2 = xmlSchemaWhiteSpaceReplace(value);
1529 if (value2 != NULL((void*)0))
1530 value = value2;
1531 }
1532 break;
1533 default:
1534 if (xmlSchemaGetCanonValue(val, &value2) == -1) {
1535 if (value2 != NULL((void*)0))
1536 xmlFree((xmlChar *) value2);
1537 goto internal_error;
1538 }
1539 if (for_hash && valType == XML_SCHEMAS_DECIMAL) {
1540 /* We can mostly use the canonical value for hashing,
1541 except in the case of decimal. There the canonical
1542 representation requires a trailing '.0' even for
1543 non-fractional numbers, but for the derived integer
1544 types it forbids any decimal point. Nevertheless they
1545 compare equal if the value is equal. We need to generate
1546 the same hash value for this to work, and it's easiest
1547 to just cut off the useless '.0' suffix for the
1548 decimal type. */
1549 int len = xmlStrlen(value2);
1550 if (len > 2 && value2[len-1] == '0' && value2[len-2] == '.')
1551 ((xmlChar*)value2)[len-2] = 0;
1552 }
1553 value = value2;
1554 }
1555 if (*retValue == NULL((void*)0))
1556 if (value == NULL((void*)0)) {
1557 if (! list)
1558 *retValue = xmlStrdup(BAD_CAST(xmlChar *) "");
1559 } else
1560 *retValue = xmlStrdup(value);
1561 else if (value != NULL((void*)0)) {
1562 /* List. */
1563 *retValue = xmlStrcat((xmlChar *) *retValue, BAD_CAST(xmlChar *) " ");
1564 *retValue = xmlStrcat((xmlChar *) *retValue, value);
1565 }
1566 FREE_AND_NULL(value2)if ((value2) != ((void*)0)) { xmlFree((xmlChar *) (value2)); value2
= ((void*)0); }
1567 val = xmlSchemaValueGetNext(val);
1568 } while (val != NULL((void*)0));
1569
1570 return (0);
1571internal_error:
1572 if (*retValue != NULL((void*)0))
1573 xmlFree((xmlChar *) (*retValue));
1574 if (value2 != NULL((void*)0))
1575 xmlFree((xmlChar *) value2);
1576 return (-1);
1577}
1578
1579static int
1580xmlSchemaGetCanonValueWhtspExt(xmlSchemaValPtr val,
1581 xmlSchemaWhitespaceValueType ws,
1582 xmlChar **retValue)
1583{
1584 return xmlSchemaGetCanonValueWhtspExt_1(val, ws, retValue, 0);
1585}
1586
1587static int
1588xmlSchemaGetCanonValueHash(xmlSchemaValPtr val,
1589 xmlChar **retValue)
1590{
1591 return xmlSchemaGetCanonValueWhtspExt_1(val, XML_SCHEMA_WHITESPACE_COLLAPSE,
1592 retValue, 1);
1593}
1594
1595/**
1596 * xmlSchemaFormatItemForReport:
1597 * @buf: the string buffer
1598 * @itemDes: the designation of the item
1599 * @itemName: the name of the item
1600 * @item: the item as an object
1601 * @itemNode: the node of the item
1602 * @local: the local name
1603 * @parsing: if the function is used during the parse
1604 *
1605 * Returns a representation of the given item used
1606 * for error reports.
1607 *
1608 * The following order is used to build the resulting
1609 * designation if the arguments are not NULL:
1610 * 1a. If itemDes not NULL -> itemDes
1611 * 1b. If (itemDes not NULL) and (itemName not NULL)
1612 * -> itemDes + itemName
1613 * 2. If the preceding was NULL and (item not NULL) -> item
1614 * 3. If the preceding was NULL and (itemNode not NULL) -> itemNode
1615 *
1616 * If the itemNode is an attribute node, the name of the attribute
1617 * will be appended to the result.
1618 *
1619 * Returns the formatted string and sets @buf to the resulting value.
1620 */
1621static xmlChar*
1622xmlSchemaFormatItemForReport(xmlChar **buf,
1623 const xmlChar *itemDes,
1624 xmlSchemaBasicItemPtr item,
1625 xmlNodePtr itemNode)
1626{
1627 xmlChar *str = NULL((void*)0);
1628 int named = 1;
1629
1630 if (*buf != NULL((void*)0)) {
1631 xmlFree(*buf);
1632 *buf = NULL((void*)0);
1633 }
1634
1635 if (itemDes != NULL((void*)0)) {
1636 *buf = xmlStrdup(itemDes);
1637 } else if (item != NULL((void*)0)) {
1638 switch (item->type) {
1639 case XML_SCHEMA_TYPE_BASIC: {
1640 xmlSchemaTypePtr type = WXS_TYPE_CAST(xmlSchemaTypePtr) item;
1641
1642 if (WXS_IS_ATOMIC(type)(type->flags & 1 << 8))
1643 *buf = xmlStrdup(BAD_CAST(xmlChar *) "atomic type 'xs:");
1644 else if (WXS_IS_LIST(type)(type->flags & 1 << 6))
1645 *buf = xmlStrdup(BAD_CAST(xmlChar *) "list type 'xs:");
1646 else if (WXS_IS_UNION(type)(type->flags & 1 << 7))
1647 *buf = xmlStrdup(BAD_CAST(xmlChar *) "union type 'xs:");
1648 else
1649 *buf = xmlStrdup(BAD_CAST(xmlChar *) "simple type 'xs:");
1650 *buf = xmlStrcat(*buf, type->name);
1651 *buf = xmlStrcat(*buf, BAD_CAST(xmlChar *) "'");
1652 }
1653 break;
1654 case XML_SCHEMA_TYPE_SIMPLE: {
1655 xmlSchemaTypePtr type = WXS_TYPE_CAST(xmlSchemaTypePtr) item;
1656
1657 if (type->flags & XML_SCHEMAS_TYPE_GLOBAL1 << 3) {
1658 *buf = xmlStrdup(BAD_CAST(xmlChar *)"");
1659 } else {
1660 *buf = xmlStrdup(BAD_CAST(xmlChar *) "local ");
1661 }
1662 if (WXS_IS_ATOMIC(type)(type->flags & 1 << 8))
1663 *buf = xmlStrcat(*buf, BAD_CAST(xmlChar *) "atomic type");
1664 else if (WXS_IS_LIST(type)(type->flags & 1 << 6))
1665 *buf = xmlStrcat(*buf, BAD_CAST(xmlChar *) "list type");
1666 else if (WXS_IS_UNION(type)(type->flags & 1 << 7))
1667 *buf = xmlStrcat(*buf, BAD_CAST(xmlChar *) "union type");
1668 else
1669 *buf = xmlStrcat(*buf, BAD_CAST(xmlChar *) "simple type");
1670 if (type->flags & XML_SCHEMAS_TYPE_GLOBAL1 << 3) {
1671 *buf = xmlStrcat(*buf, BAD_CAST(xmlChar *) " '");
1672 *buf = xmlStrcat(*buf, type->name);
1673 *buf = xmlStrcat(*buf, BAD_CAST(xmlChar *) "'");
1674 }
1675 }
1676 break;
1677 case XML_SCHEMA_TYPE_COMPLEX: {
1678 xmlSchemaTypePtr type = WXS_TYPE_CAST(xmlSchemaTypePtr) item;
1679
1680 if (type->flags & XML_SCHEMAS_TYPE_GLOBAL1 << 3)
1681 *buf = xmlStrdup(BAD_CAST(xmlChar *) "");
1682 else
1683 *buf = xmlStrdup(BAD_CAST(xmlChar *) "local ");
1684 *buf = xmlStrcat(*buf, BAD_CAST(xmlChar *) "complex type");
1685 if (type->flags & XML_SCHEMAS_TYPE_GLOBAL1 << 3) {
1686 *buf = xmlStrcat(*buf, BAD_CAST(xmlChar *) " '");
1687 *buf = xmlStrcat(*buf, type->name);
1688 *buf = xmlStrcat(*buf, BAD_CAST(xmlChar *) "'");
1689 }
1690 }
1691 break;
1692 case XML_SCHEMA_TYPE_ATTRIBUTE_USE: {
1693 xmlSchemaAttributeUsePtr ause;
1694
1695 ause = WXS_ATTR_USE_CAST(xmlSchemaAttributeUsePtr) item;
1696 *buf = xmlStrdup(BAD_CAST(xmlChar *) "attribute use ");
1697 if (WXS_ATTRUSE_DECL(ause)((xmlSchemaAttributeUsePtr) (ause))->attrDecl != NULL((void*)0)) {
1698 *buf = xmlStrcat(*buf, BAD_CAST(xmlChar *) "'");
1699 *buf = xmlStrcat(*buf,
1700 xmlSchemaGetComponentQName(&str, WXS_ATTRUSE_DECL(ause)((xmlSchemaAttributeUsePtr) (ause))->attrDecl));
1701 FREE_AND_NULL(str)if ((str) != ((void*)0)) { xmlFree((xmlChar *) (str)); str = (
(void*)0); }
1702 *buf = xmlStrcat(*buf, BAD_CAST(xmlChar *) "'");
1703 } else {
1704 *buf = xmlStrcat(*buf, BAD_CAST(xmlChar *) "(unknown)");
1705 }
1706 }
1707 break;
1708 case XML_SCHEMA_TYPE_ATTRIBUTE: {
1709 xmlSchemaAttributePtr attr;
1710
1711 attr = (xmlSchemaAttributePtr) item;
1712 *buf = xmlStrdup(BAD_CAST(xmlChar *) "attribute decl.");
1713 *buf = xmlStrcat(*buf, BAD_CAST(xmlChar *) " '");
1714 *buf = xmlStrcat(*buf, xmlSchemaFormatQName(&str,
1715 attr->targetNamespace, attr->name));
1716 FREE_AND_NULL(str)if ((str) != ((void*)0)) { xmlFree((xmlChar *) (str)); str = (
(void*)0); }
1717 *buf = xmlStrcat(*buf, BAD_CAST(xmlChar *) "'");
1718 }
1719 break;
1720 case XML_SCHEMA_TYPE_ATTRIBUTEGROUP:
1721 xmlSchemaGetComponentDesignation(buf, item);
1722 break;
1723 case XML_SCHEMA_TYPE_ELEMENT: {
1724 xmlSchemaElementPtr elem;
1725
1726 elem = (xmlSchemaElementPtr) item;
1727 *buf = xmlStrdup(BAD_CAST(xmlChar *) "element decl.");
1728 *buf = xmlStrcat(*buf, BAD_CAST(xmlChar *) " '");
1729 *buf = xmlStrcat(*buf, xmlSchemaFormatQName(&str,
1730 elem->targetNamespace, elem->name));
1731 *buf = xmlStrcat(*buf, BAD_CAST(xmlChar *) "'");
1732 }
1733 break;
1734 case XML_SCHEMA_TYPE_IDC_UNIQUE:
1735 case XML_SCHEMA_TYPE_IDC_KEY:
1736 case XML_SCHEMA_TYPE_IDC_KEYREF:
1737 if (item->type == XML_SCHEMA_TYPE_IDC_UNIQUE)
1738 *buf = xmlStrdup(BAD_CAST(xmlChar *) "unique '");
1739 else if (item->type == XML_SCHEMA_TYPE_IDC_KEY)
1740 *buf = xmlStrdup(BAD_CAST(xmlChar *) "key '");
1741 else
1742 *buf = xmlStrdup(BAD_CAST(xmlChar *) "keyRef '");
1743 *buf = xmlStrcat(*buf, ((xmlSchemaIDCPtr) item)->name);
1744 *buf = xmlStrcat(*buf, BAD_CAST(xmlChar *) "'");
1745 break;
1746 case XML_SCHEMA_TYPE_ANY:
1747 case XML_SCHEMA_TYPE_ANY_ATTRIBUTE:
1748 *buf = xmlStrdup(xmlSchemaWildcardPCToString(
1749 ((xmlSchemaWildcardPtr) item)->processContents));
1750 *buf = xmlStrcat(*buf, BAD_CAST(xmlChar *) " wildcard");
1751 break;
1752 case XML_SCHEMA_FACET_MININCLUSIVE:
1753 case XML_SCHEMA_FACET_MINEXCLUSIVE:
1754 case XML_SCHEMA_FACET_MAXINCLUSIVE:
1755 case XML_SCHEMA_FACET_MAXEXCLUSIVE:
1756 case XML_SCHEMA_FACET_TOTALDIGITS:
1757 case XML_SCHEMA_FACET_FRACTIONDIGITS:
1758 case XML_SCHEMA_FACET_PATTERN:
1759 case XML_SCHEMA_FACET_ENUMERATION:
1760 case XML_SCHEMA_FACET_WHITESPACE:
1761 case XML_SCHEMA_FACET_LENGTH:
1762 case XML_SCHEMA_FACET_MAXLENGTH:
1763 case XML_SCHEMA_FACET_MINLENGTH:
1764 *buf = xmlStrdup(BAD_CAST(xmlChar *) "facet '");
1765 *buf = xmlStrcat(*buf, xmlSchemaFacetTypeToString(item->type));
1766 *buf = xmlStrcat(*buf, BAD_CAST(xmlChar *) "'");
1767 break;
1768 case XML_SCHEMA_TYPE_GROUP: {
1769 *buf = xmlStrdup(BAD_CAST(xmlChar *) "model group def.");
1770 *buf = xmlStrcat(*buf, BAD_CAST(xmlChar *) " '");
1771 *buf = xmlStrcat(*buf, xmlSchemaGetComponentQName(&str, item));
1772 *buf = xmlStrcat(*buf, BAD_CAST(xmlChar *) "'");
1773 FREE_AND_NULL(str)if ((str) != ((void*)0)) { xmlFree((xmlChar *) (str)); str = (
(void*)0); }
1774 }
1775 break;
1776 case XML_SCHEMA_TYPE_SEQUENCE:
1777 case XML_SCHEMA_TYPE_CHOICE:
1778 case XML_SCHEMA_TYPE_ALL:
1779 case XML_SCHEMA_TYPE_PARTICLE:
1780 *buf = xmlStrdup(WXS_ITEM_TYPE_NAME(item)xmlSchemaGetComponentTypeStr((xmlSchemaBasicItemPtr) (item)));
1781 break;
1782 case XML_SCHEMA_TYPE_NOTATION: {
1783 *buf = xmlStrdup(WXS_ITEM_TYPE_NAME(item)xmlSchemaGetComponentTypeStr((xmlSchemaBasicItemPtr) (item)));
1784 *buf = xmlStrcat(*buf, BAD_CAST(xmlChar *) " '");
1785 *buf = xmlStrcat(*buf, xmlSchemaGetComponentQName(&str, item));
1786 *buf = xmlStrcat(*buf, BAD_CAST(xmlChar *) "'");
1787 FREE_AND_NULL(str)if ((str) != ((void*)0)) { xmlFree((xmlChar *) (str)); str = (
(void*)0); }
;
1788 }
1789 /* Falls through. */
1790 default:
1791 named = 0;
1792 }
1793 } else
1794 named = 0;
1795
1796 if ((named == 0) && (itemNode != NULL((void*)0))) {
1797 xmlNodePtr elem;
1798
1799 if (itemNode->type == XML_ATTRIBUTE_NODE)
1800 elem = itemNode->parent;
1801 else
1802 elem = itemNode;
1803 *buf = xmlStrdup(BAD_CAST(xmlChar *) "Element '");
1804 if (elem->ns != NULL((void*)0)) {
1805 *buf = xmlStrcat(*buf,
1806 xmlSchemaFormatQName(&str, elem->ns->href, elem->name));
1807 FREE_AND_NULL(str)if ((str) != ((void*)0)) { xmlFree((xmlChar *) (str)); str = (
(void*)0); }
1808 } else
1809 *buf = xmlStrcat(*buf, elem->name);
1810 *buf = xmlStrcat(*buf, BAD_CAST(xmlChar *) "'");
1811
1812 }
1813 if ((itemNode != NULL((void*)0)) && (itemNode->type == XML_ATTRIBUTE_NODE)) {
1814 *buf = xmlStrcat(*buf, BAD_CAST(xmlChar *) ", attribute '");
1815 if (itemNode->ns != NULL((void*)0)) {
1816 *buf = xmlStrcat(*buf, xmlSchemaFormatQName(&str,
1817 itemNode->ns->href, itemNode->name));
1818 FREE_AND_NULL(str)if ((str) != ((void*)0)) { xmlFree((xmlChar *) (str)); str = (
(void*)0); }
1819 } else
1820 *buf = xmlStrcat(*buf, itemNode->name);
1821 *buf = xmlStrcat(*buf, BAD_CAST(xmlChar *) "'");
1822 }
1823 FREE_AND_NULL(str)if ((str) != ((void*)0)) { xmlFree((xmlChar *) (str)); str = (
(void*)0); }
1824
1825 return (xmlEscapeFormatString(buf));
1826}
1827
1828/**
1829 * xmlSchemaFormatFacetEnumSet:
1830 * @buf: the string buffer
1831 * @type: the type holding the enumeration facets
1832 *
1833 * Builds a string consisting of all enumeration elements.
1834 *
1835 * Returns a string of all enumeration elements.
1836 */
1837static const xmlChar *
1838xmlSchemaFormatFacetEnumSet(xmlSchemaAbstractCtxtPtr actxt,
1839 xmlChar **buf, xmlSchemaTypePtr type)
1840{
1841 xmlSchemaFacetPtr facet;
1842 xmlSchemaWhitespaceValueType ws;
1843 xmlChar *value = NULL((void*)0);
1844 int res, found = 0;
1845
1846 if (*buf != NULL((void*)0))
1847 xmlFree(*buf);
1848 *buf = NULL((void*)0);
1849
1850 do {
1851 /*
1852 * Use the whitespace type of the base type.
1853 */
1854 ws = xmlSchemaGetWhiteSpaceFacetValue(type->baseType);
1855 for (facet = type->facets; facet != NULL((void*)0); facet = facet->next) {
1856 if (facet->type != XML_SCHEMA_FACET_ENUMERATION)
1857 continue;
1858 found = 1;
1859 res = xmlSchemaGetCanonValueWhtspExt(facet->val,
1860 ws, &value);
1861 if (res == -1) {
1862 xmlSchemaInternalErr(actxt,
1863 "xmlSchemaFormatFacetEnumSet",
1864 "compute the canonical lexical representation");
1865 if (*buf != NULL((void*)0))
1866 xmlFree(*buf);
1867 *buf = NULL((void*)0);
1868 return (NULL((void*)0));
1869 }
1870 if (*buf == NULL((void*)0))
1871 *buf = xmlStrdup(BAD_CAST(xmlChar *) "'");
1872 else
1873 *buf = xmlStrcat(*buf, BAD_CAST(xmlChar *) ", '");
1874 *buf = xmlStrcat(*buf, BAD_CAST(xmlChar *) value);
1875 *buf = xmlStrcat(*buf, BAD_CAST(xmlChar *) "'");
1876 if (value != NULL((void*)0)) {
1877 xmlFree((xmlChar *)value);
1878 value = NULL((void*)0);
1879 }
1880 }
1881 /*
1882 * The enumeration facet of a type restricts the enumeration
1883 * facet of the ancestor type; i.e., such restricted enumerations
1884 * do not belong to the set of the given type. Thus we break
1885 * on the first found enumeration.
1886 */
1887 if (found)
1888 break;
1889 type = type->baseType;
1890 } while ((type != NULL((void*)0)) && (type->type != XML_SCHEMA_TYPE_BASIC));
1891
1892 return ((const xmlChar *) *buf);
1893}
1894
1895/************************************************************************
1896 * *
1897 * Error functions *
1898 * *
1899 ************************************************************************/
1900
1901#if 0
1902static void
1903xmlSchemaErrMemory(const char *msg)
1904{
1905 __xmlSimpleError(XML_FROM_SCHEMASP, XML_ERR_NO_MEMORY, NULL((void*)0), NULL((void*)0),
1906 msg);
1907}
1908#endif
1909
1910static void
1911xmlSchemaPSimpleErr(const char *msg)
1912{
1913 __xmlSimpleError(XML_FROM_SCHEMASP, XML_ERR_NO_MEMORY, NULL((void*)0), NULL((void*)0),
1914 msg);
1915}
1916
1917/**
1918 * xmlSchemaPErrMemory:
1919 * @node: a context node
1920 * @extra: extra information
1921 *
1922 * Handle an out of memory condition
1923 */
1924static void
1925xmlSchemaPErrMemory(xmlSchemaParserCtxtPtr ctxt,
1926 const char *extra, xmlNodePtr node)
1927{
1928 if (ctxt != NULL((void*)0))
1929 ctxt->nberrors++;
1930 __xmlSimpleError(XML_FROM_SCHEMASP, XML_ERR_NO_MEMORY, node, NULL((void*)0),
1931 extra);
1932}
1933
1934/**
1935 * xmlSchemaPErr:
1936 * @ctxt: the parsing context
1937 * @node: the context node
1938 * @error: the error code
1939 * @msg: the error message
1940 * @str1: extra data
1941 * @str2: extra data
1942 *
1943 * Handle a parser error
1944 */
1945static void LIBXML_ATTR_FORMAT(4,0)__attribute__((__format__(__printf__,4,0)))
1946xmlSchemaPErr(xmlSchemaParserCtxtPtr ctxt, xmlNodePtr node, int error,
1947 const char *msg, const xmlChar * str1, const xmlChar * str2)
1948{
1949 xmlGenericErrorFunc channel = NULL((void*)0);
1950 xmlStructuredErrorFunc schannel = NULL((void*)0);
1951 void *data = NULL((void*)0);
1952
1953 if (ctxt != NULL((void*)0)) {
1954 ctxt->nberrors++;
1955 ctxt->err = error;
1956 channel = ctxt->error;
1957 data = ctxt->errCtxt;
1958 schannel = ctxt->serror;
1959 }
1960 __xmlRaiseError(schannel, channel, data, ctxt, node, XML_FROM_SCHEMASP,
1961 error, XML_ERR_ERROR, NULL((void*)0), 0,
1962 (const char *) str1, (const char *) str2, NULL((void*)0), 0, 0,
1963 msg, str1, str2);
1964}
1965
1966/**
1967 * xmlSchemaPErr2:
1968 * @ctxt: the parsing context
1969 * @node: the context node
1970 * @node: the current child
1971 * @error: the error code
1972 * @msg: the error message
1973 * @str1: extra data
1974 * @str2: extra data
1975 *
1976 * Handle a parser error
1977 */
1978static void LIBXML_ATTR_FORMAT(5,0)__attribute__((__format__(__printf__,5,0)))
1979xmlSchemaPErr2(xmlSchemaParserCtxtPtr ctxt, xmlNodePtr node,
1980 xmlNodePtr child, int error,
1981 const char *msg, const xmlChar * str1, const xmlChar * str2)
1982{
1983 if (child != NULL((void*)0))
1984 xmlSchemaPErr(ctxt, child, error, msg, str1, str2);
1985 else
1986 xmlSchemaPErr(ctxt, node, error, msg, str1, str2);
1987}
1988
1989
1990/**
1991 * xmlSchemaPErrExt:
1992 * @ctxt: the parsing context
1993 * @node: the context node
1994 * @error: the error code
1995 * @strData1: extra data
1996 * @strData2: extra data
1997 * @strData3: extra data
1998 * @msg: the message
1999 * @str1: extra parameter for the message display
2000 * @str2: extra parameter for the message display
2001 * @str3: extra parameter for the message display
2002 * @str4: extra parameter for the message display
2003 * @str5: extra parameter for the message display
2004 *
2005 * Handle a parser error
2006 */
2007static void LIBXML_ATTR_FORMAT(7,0)__attribute__((__format__(__printf__,7,0)))
2008xmlSchemaPErrExt(xmlSchemaParserCtxtPtr ctxt, xmlNodePtr node, int error,
2009 const xmlChar * strData1, const xmlChar * strData2,
2010 const xmlChar * strData3, const char *msg, const xmlChar * str1,
2011 const xmlChar * str2, const xmlChar * str3, const xmlChar * str4,
2012 const xmlChar * str5)
2013{
2014
2015 xmlGenericErrorFunc channel = NULL((void*)0);
2016 xmlStructuredErrorFunc schannel = NULL((void*)0);
2017 void *data = NULL((void*)0);
2018
2019 if (ctxt != NULL((void*)0)) {
2020 ctxt->nberrors++;
2021 ctxt->err = error;
2022 channel = ctxt->error;
2023 data = ctxt->errCtxt;
2024 schannel = ctxt->serror;
2025 }
2026 __xmlRaiseError(schannel, channel, data, ctxt, node, XML_FROM_SCHEMASP,
2027 error, XML_ERR_ERROR, NULL((void*)0), 0,
2028 (const char *) strData1, (const char *) strData2,
2029 (const char *) strData3, 0, 0, msg, str1, str2,
2030 str3, str4, str5);
2031}
2032
2033/************************************************************************
2034 * *
2035 * Allround error functions *
2036 * *
2037 ************************************************************************/
2038
2039/**
2040 * xmlSchemaVTypeErrMemory:
2041 * @node: a context node
2042 * @extra: extra information
2043 *
2044 * Handle an out of memory condition
2045 */
2046static void
2047xmlSchemaVErrMemory(xmlSchemaValidCtxtPtr ctxt,
2048 const char *extra, xmlNodePtr node)
2049{
2050 if (ctxt != NULL((void*)0)) {
2051 ctxt->nberrors++;
2052 ctxt->err = XML_SCHEMAV_INTERNAL;
2053 }
2054 __xmlSimpleError(XML_FROM_SCHEMASV, XML_ERR_NO_MEMORY, node, NULL((void*)0),
2055 extra);
2056}
2057
2058static void LIBXML_ATTR_FORMAT(2,0)__attribute__((__format__(__printf__,2,0)))
2059xmlSchemaPSimpleInternalErr(xmlNodePtr node,
2060 const char *msg, const xmlChar *str)
2061{
2062 __xmlSimpleError(XML_FROM_SCHEMASP, XML_SCHEMAP_INTERNAL, node,
2063 msg, (const char *) str);
2064}
2065
2066#define WXS_ERROR_TYPE_ERROR1 1
2067#define WXS_ERROR_TYPE_WARNING2 2
2068/**
2069 * xmlSchemaErr4Line:
2070 * @ctxt: the validation context
2071 * @errorLevel: the error level
2072 * @error: the error code
2073 * @node: the context node
2074 * @line: the line number
2075 * @msg: the error message
2076 * @str1: extra data
2077 * @str2: extra data
2078 * @str3: extra data
2079 * @str4: extra data
2080 *
2081 * Handle a validation error
2082 */
2083static void LIBXML_ATTR_FORMAT(6,0)__attribute__((__format__(__printf__,6,0)))
2084xmlSchemaErr4Line(xmlSchemaAbstractCtxtPtr ctxt,
2085 xmlErrorLevel errorLevel,
2086 int error, xmlNodePtr node, int line, const char *msg,
2087 const xmlChar *str1, const xmlChar *str2,
2088 const xmlChar *str3, const xmlChar *str4)
2089{
2090 xmlStructuredErrorFunc schannel = NULL((void*)0);
2091 xmlGenericErrorFunc channel = NULL((void*)0);
2092 void *data = NULL((void*)0);
2093
2094 if (ctxt != NULL((void*)0)) {
2095 if (ctxt->type == XML_SCHEMA_CTXT_VALIDATOR2) {
2096 xmlSchemaValidCtxtPtr vctxt = (xmlSchemaValidCtxtPtr) ctxt;
2097 const char *file = NULL((void*)0);
2098 int col = 0;
2099 if (errorLevel != XML_ERR_WARNING) {
2100 vctxt->nberrors++;
2101 vctxt->err = error;
2102 channel = vctxt->error;
2103 } else {
2104 channel = vctxt->warning;
2105 }
2106 schannel = vctxt->serror;
2107 data = vctxt->errCtxt;
2108
2109 /*
2110 * Error node. If we specify a line number, then
2111 * do not channel any node to the error function.
2112 */
2113 if (line == 0) {
2114 if ((node == NULL((void*)0)) &&
2115 (vctxt->depth >= 0) &&
2116 (vctxt->inode != NULL((void*)0))) {
2117 node = vctxt->inode->node;
2118 }
2119 /*
2120 * Get filename and line if no node-tree.
2121 */
2122 if ((node == NULL((void*)0)) &&
2123 (vctxt->parserCtxt != NULL((void*)0)) &&
2124 (vctxt->parserCtxt->input != NULL((void*)0))) {
2125 file = vctxt->parserCtxt->input->filename;
2126 if (vctxt->inode != NULL((void*)0)) {
2127 line = vctxt->inode->nodeLine;
2128 col = 0;
2129 } else {
2130 /* This is inaccurate. */
2131 line = vctxt->parserCtxt->input->line;
2132 col = vctxt->parserCtxt->input->col;
2133 }
2134 }
2135 } else {
2136 /*
2137 * Override the given node's (if any) position
2138 * and channel only the given line number.
2139 */
2140 node = NULL((void*)0);
2141 /*
2142 * Get filename.
2143 */
2144 if (vctxt->doc != NULL((void*)0))
2145 file = (const char *) vctxt->doc->URL;
2146 else if ((vctxt->parserCtxt != NULL((void*)0)) &&
2147 (vctxt->parserCtxt->input != NULL((void*)0)))
2148 file = vctxt->parserCtxt->input->filename;
2149 }
2150 if (vctxt->locFunc != NULL((void*)0)) {
2151 if ((file == NULL((void*)0)) || (line == 0)) {
2152 unsigned long l;
2153 const char *f;
2154 vctxt->locFunc(vctxt->locCtxt, &f, &l);
2155 if (file == NULL((void*)0))
2156 file = f;
2157 if (line == 0)
2158 line = (int) l;
2159 }
2160 }
2161 if ((file == NULL((void*)0)) && (vctxt->filename != NULL((void*)0)))
2162 file = vctxt->filename;
2163
2164 __xmlRaiseError(schannel, channel, data, ctxt,
2165 node, XML_FROM_SCHEMASV,
2166 error, errorLevel, file, line,
2167 (const char *) str1, (const char *) str2,
2168 (const char *) str3, 0, col, msg, str1, str2, str3, str4);
2169
2170 } else if (ctxt->type == XML_SCHEMA_CTXT_PARSER1) {
2171 xmlSchemaParserCtxtPtr pctxt = (xmlSchemaParserCtxtPtr) ctxt;
2172 if (errorLevel != XML_ERR_WARNING) {
2173 pctxt->nberrors++;
2174 pctxt->err = error;
2175 channel = pctxt->error;
2176 } else {
2177 channel = pctxt->warning;
2178 }
2179 schannel = pctxt->serror;
2180 data = pctxt->errCtxt;
2181 __xmlRaiseError(schannel, channel, data, ctxt,
2182 node, XML_FROM_SCHEMASP, error,
2183 errorLevel, NULL((void*)0), 0,
2184 (const char *) str1, (const char *) str2,
2185 (const char *) str3, 0, 0, msg, str1, str2, str3, str4);
2186 } else {
2187 TODO(*__xmlGenericError())((*__xmlGenericErrorContext()), "Unimplemented block at %s:%d\n"
, "xmlschemas.c", 2187);
2188 }
2189 }
2190}
2191
2192/**
2193 * xmlSchemaErr3:
2194 * @ctxt: the validation context
2195 * @node: the context node
2196 * @error: the error code
2197 * @msg: the error message
2198 * @str1: extra data
2199 * @str2: extra data
2200 * @str3: extra data
2201 *
2202 * Handle a validation error
2203 */
2204static void LIBXML_ATTR_FORMAT(4,0)__attribute__((__format__(__printf__,4,0)))
2205xmlSchemaErr3(xmlSchemaAbstractCtxtPtr actxt,
2206 int error, xmlNodePtr node, const char *msg,
2207 const xmlChar *str1, const xmlChar *str2, const xmlChar *str3)
2208{
2209 xmlSchemaErr4Line(actxt, XML_ERR_ERROR, error, node, 0,
2210 msg, str1, str2, str3, NULL((void*)0));
2211}
2212
2213static void LIBXML_ATTR_FORMAT(4,0)__attribute__((__format__(__printf__,4,0)))
2214xmlSchemaErr4(xmlSchemaAbstractCtxtPtr actxt,
2215 int error, xmlNodePtr node, const char *msg,
2216 const xmlChar *str1, const xmlChar *str2,
2217 const xmlChar *str3, const xmlChar *str4)
2218{
2219 xmlSchemaErr4Line(actxt, XML_ERR_ERROR, error, node, 0,
2220 msg, str1, str2, str3, str4);
2221}
2222
2223static void LIBXML_ATTR_FORMAT(4,0)__attribute__((__format__(__printf__,4,0)))
2224xmlSchemaErr(xmlSchemaAbstractCtxtPtr actxt,
2225 int error, xmlNodePtr node, const char *msg,
2226 const xmlChar *str1, const xmlChar *str2)
2227{
2228 xmlSchemaErr4(actxt, error, node, msg, str1, str2, NULL((void*)0), NULL((void*)0));
2229}
2230
2231static xmlChar *
2232xmlSchemaFormatNodeForError(xmlChar ** msg,
2233 xmlSchemaAbstractCtxtPtr actxt,
2234 xmlNodePtr node)
2235{
2236 xmlChar *str = NULL((void*)0);
2237
2238 *msg = NULL((void*)0);
2239 if ((node != NULL((void*)0)) &&
2240 (node->type != XML_ELEMENT_NODE) &&
2241 (node->type != XML_ATTRIBUTE_NODE))
2242 {
2243 /*
2244 * Don't try to format other nodes than element and
2245 * attribute nodes.
2246 * Play safe and return an empty string.
2247 */
2248 *msg = xmlStrdup(BAD_CAST(xmlChar *) "");
2249 return(*msg);
2250 }
2251 if (node != NULL((void*)0)) {
2252 /*
2253 * Work on tree nodes.
2254 */
2255 if (node->type == XML_ATTRIBUTE_NODE) {
2256 xmlNodePtr elem = node->parent;
2257
2258 *msg = xmlStrdup(BAD_CAST(xmlChar *) "Element '");
2259 if (elem->ns != NULL((void*)0))
2260 *msg = xmlStrcat(*msg, xmlSchemaFormatQName(&str,
2261 elem->ns->href, elem->name));
2262 else
2263 *msg = xmlStrcat(*msg, xmlSchemaFormatQName(&str,
2264 NULL((void*)0), elem->name));
2265 FREE_AND_NULL(str)if ((str) != ((void*)0)) { xmlFree((xmlChar *) (str)); str = (
(void*)0); }
;
2266 *msg = xmlStrcat(*msg, BAD_CAST(xmlChar *) "', ");
2267 *msg = xmlStrcat(*msg, BAD_CAST(xmlChar *) "attribute '");
2268 } else {
2269 *msg = xmlStrdup(BAD_CAST(xmlChar *) "Element '");
2270 }
2271 if (node->ns != NULL((void*)0))
2272 *msg = xmlStrcat(*msg, xmlSchemaFormatQName(&str,
2273 node->ns->href, node->name));
2274 else
2275 *msg = xmlStrcat(*msg, xmlSchemaFormatQName(&str,
2276 NULL((void*)0), node->name));
2277 FREE_AND_NULL(str)if ((str) != ((void*)0)) { xmlFree((xmlChar *) (str)); str = (
(void*)0); }
;
2278 *msg = xmlStrcat(*msg, BAD_CAST(xmlChar *) "': ");
2279 } else if (actxt->type == XML_SCHEMA_CTXT_VALIDATOR2) {
2280 xmlSchemaValidCtxtPtr vctxt = (xmlSchemaValidCtxtPtr) actxt;
2281 /*
2282 * Work on node infos.
2283 */
2284 if (vctxt->inode->nodeType == XML_ATTRIBUTE_NODE) {
2285 xmlSchemaNodeInfoPtr ielem =
2286 vctxt->elemInfos[vctxt->depth];
2287
2288 *msg = xmlStrdup(BAD_CAST(xmlChar *) "Element '");
2289 *msg = xmlStrcat(*msg, xmlSchemaFormatQName(&str,
2290 ielem->nsName, ielem->localName));
2291 FREE_AND_NULL(str)if ((str) != ((void*)0)) { xmlFree((xmlChar *) (str)); str = (
(void*)0); }
;
2292 *msg = xmlStrcat(*msg, BAD_CAST(xmlChar *) "', ");
2293 *msg = xmlStrcat(*msg, BAD_CAST(xmlChar *) "attribute '");
2294 } else {
2295 *msg = xmlStrdup(BAD_CAST(xmlChar *) "Element '");
2296 }
2297 *msg = xmlStrcat(*msg, xmlSchemaFormatQName(&str,
2298 vctxt->inode->nsName, vctxt->inode->localName));
2299 FREE_AND_NULL(str)if ((str) != ((void*)0)) { xmlFree((xmlChar *) (str)); str = (
(void*)0); }
;
2300 *msg = xmlStrcat(*msg, BAD_CAST(xmlChar *) "': ");
2301 } else if (actxt->type == XML_SCHEMA_CTXT_PARSER1) {
2302 /*
2303 * Hmm, no node while parsing?
2304 * Return an empty string, in case NULL will break something.
2305 */
2306 *msg = xmlStrdup(BAD_CAST(xmlChar *) "");
2307 } else {
2308 TODO(*__xmlGenericError())((*__xmlGenericErrorContext()), "Unimplemented block at %s:%d\n"
, "xmlschemas.c", 2308);
2309 return (NULL((void*)0));
2310 }
2311
2312 /*
2313 * xmlSchemaFormatItemForReport() also returns an escaped format
2314 * string, so do this before calling it below (in the future).
2315 */
2316 xmlEscapeFormatString(msg);
2317
2318 /*
2319 * VAL TODO: The output of the given schema component is currently
2320 * disabled.
2321 */
2322#if 0
2323 if ((type != NULL((void*)0)) && (xmlSchemaIsGlobalItem(type))) {
2324 *msg = xmlStrcat(*msg, BAD_CAST(xmlChar *) " [");
2325 *msg = xmlStrcat(*msg, xmlSchemaFormatItemForReport(&str,
2326 NULL((void*)0), type, NULL((void*)0), 0));
2327 FREE_AND_NULL(str)if ((str) != ((void*)0)) { xmlFree((xmlChar *) (str)); str = (
(void*)0); }
2328 *msg = xmlStrcat(*msg, BAD_CAST(xmlChar *) "]");
2329 }
2330#endif
2331 return (*msg);
2332}
2333
2334static void LIBXML_ATTR_FORMAT(3,0)__attribute__((__format__(__printf__,3,0)))
2335xmlSchemaInternalErr2(xmlSchemaAbstractCtxtPtr actxt,
2336 const char *funcName,
2337 const char *message,
2338 const xmlChar *str1,
2339 const xmlChar *str2)
2340{
2341 xmlChar *msg = NULL((void*)0);
2342
2343 if (actxt == NULL((void*)0))
2344 return;
2345 msg = xmlStrdup(BAD_CAST(xmlChar *) "Internal error: %s, ");
2346 msg = xmlStrcat(msg, BAD_CAST(xmlChar *) message);
2347 msg = xmlStrcat(msg, BAD_CAST(xmlChar *) ".\n");
2348
2349 if (actxt->type == XML_SCHEMA_CTXT_VALIDATOR2)
2350 xmlSchemaErr3(actxt, XML_SCHEMAV_INTERNAL, NULL((void*)0),
2351 (const char *) msg, (const xmlChar *) funcName, str1, str2);
2352 else if (actxt->type == XML_SCHEMA_CTXT_PARSER1)
2353 xmlSchemaErr3(actxt, XML_SCHEMAP_INTERNAL, NULL((void*)0),
2354 (const char *) msg, (const xmlChar *) funcName, str1, str2);
2355
2356 FREE_AND_NULL(msg)if ((msg) != ((void*)0)) { xmlFree((xmlChar *) (msg)); msg = (
(void*)0); }
2357}
2358
2359static void LIBXML_ATTR_FORMAT(3,0)__attribute__((__format__(__printf__,3,0)))
2360xmlSchemaInternalErr(xmlSchemaAbstractCtxtPtr actxt,
2361 const char *funcName,
2362 const char *message)
2363{
2364 xmlSchemaInternalErr2(actxt, funcName, message, NULL((void*)0), NULL((void*)0));
2365}
2366
2367#if 0
2368static void LIBXML_ATTR_FORMAT(3,0)__attribute__((__format__(__printf__,3,0)))
2369xmlSchemaPInternalErr(xmlSchemaParserCtxtPtr pctxt,
2370 const char *funcName,
2371 const char *message,
2372 const xmlChar *str1,
2373 const xmlChar *str2)
2374{
2375 xmlSchemaInternalErr2(ACTXT_CAST(xmlSchemaAbstractCtxtPtr) pctxt, funcName, message,
2376 str1, str2);
2377}
2378#endif
2379
2380static void LIBXML_ATTR_FORMAT(5,0)__attribute__((__format__(__printf__,5,0)))
2381xmlSchemaCustomErr4(xmlSchemaAbstractCtxtPtr actxt,
2382 xmlParserErrors error,
2383 xmlNodePtr node,
2384 xmlSchemaBasicItemPtr item,
2385 const char *message,
2386 const xmlChar *str1, const xmlChar *str2,
2387 const xmlChar *str3, const xmlChar *str4)
2388{
2389 xmlChar *msg = NULL((void*)0);
2390
2391 if ((node == NULL((void*)0)) && (item != NULL((void*)0)) &&
2392 (actxt->type == XML_SCHEMA_CTXT_PARSER1)) {
2393 node = WXS_ITEM_NODE(item)xmlSchemaGetComponentNode((xmlSchemaBasicItemPtr) (item));
2394 xmlSchemaFormatItemForReport(&msg, NULL((void*)0), item, NULL((void*)0));
2395 msg = xmlStrcat(msg, BAD_CAST(xmlChar *) ": ");
2396 } else
2397 xmlSchemaFormatNodeForError(&msg, actxt, node);
2398 msg = xmlStrcat(msg, (const xmlChar *) message);
2399 msg = xmlStrcat(msg, BAD_CAST(xmlChar *) ".\n");
2400 xmlSchemaErr4(actxt, error, node,
2401 (const char *) msg, str1, str2, str3, str4);
2402 FREE_AND_NULL(msg)if ((msg) != ((void*)0)) { xmlFree((xmlChar *) (msg)); msg = (
(void*)0); }
2403}
2404
2405static void LIBXML_ATTR_FORMAT(5,0)__attribute__((__format__(__printf__,5,0)))
2406xmlSchemaCustomErr(xmlSchemaAbstractCtxtPtr actxt,
2407 xmlParserErrors error,
2408 xmlNodePtr node,
2409 xmlSchemaBasicItemPtr item,
2410 const char *message,
2411 const xmlChar *str1,
2412 const xmlChar *str2)
2413{
2414 xmlSchemaCustomErr4(actxt, error, node, item,
2415 message, str1, str2, NULL((void*)0), NULL((void*)0));
2416}
2417
2418
2419
2420static void LIBXML_ATTR_FORMAT(5,0)__attribute__((__format__(__printf__,5,0)))
2421xmlSchemaCustomWarning(xmlSchemaAbstractCtxtPtr actxt,
2422 xmlParserErrors error,
2423 xmlNodePtr node,
2424 xmlSchemaTypePtr type ATTRIBUTE_UNUSED__attribute__((unused)),
2425 const char *message,
2426 const xmlChar *str1,
2427 const xmlChar *str2,
2428 const xmlChar *str3)
2429{
2430 xmlChar *msg = NULL((void*)0);
2431
2432 xmlSchemaFormatNodeForError(&msg, actxt, node);
2433 msg = xmlStrcat(msg, (const xmlChar *) message);
2434 msg = xmlStrcat(msg, BAD_CAST(xmlChar *) ".\n");
2435
2436 /* URGENT TODO: Set the error code to something sane. */
2437 xmlSchemaErr4Line(actxt, XML_ERR_WARNING, error, node, 0,
2438 (const char *) msg, str1, str2, str3, NULL((void*)0));
2439
2440 FREE_AND_NULL(msg)if ((msg) != ((void*)0)) { xmlFree((xmlChar *) (msg)); msg = (
(void*)0); }
2441}
2442
2443
2444
2445static void LIBXML_ATTR_FORMAT(5,0)__attribute__((__format__(__printf__,5,0)))
2446xmlSchemaKeyrefErr(xmlSchemaValidCtxtPtr vctxt,
2447 xmlParserErrors error,
2448 xmlSchemaPSVIIDCNodePtr idcNode,
2449 xmlSchemaTypePtr type ATTRIBUTE_UNUSED__attribute__((unused)),
2450 const char *message,
2451 const xmlChar *str1,
2452 const xmlChar *str2)
2453{
2454 xmlChar *msg = NULL((void*)0), *qname = NULL((void*)0);
2455
2456 msg = xmlStrdup(BAD_CAST(xmlChar *) "Element '%s': ");
2457 msg = xmlStrcat(msg, (const xmlChar *) message);
2458 msg = xmlStrcat(msg, BAD_CAST(xmlChar *) ".\n");
2459 xmlSchemaErr4Line(ACTXT_CAST(xmlSchemaAbstractCtxtPtr) vctxt, XML_ERR_ERROR,
2460 error, NULL((void*)0), idcNode->nodeLine, (const char *) msg,
2461 xmlSchemaFormatQName(&qname,
2462 vctxt->nodeQNames->items[idcNode->nodeQNameID +1],
2463 vctxt->nodeQNames->items[idcNode->nodeQNameID]),
2464 str1, str2, NULL((void*)0));
2465 FREE_AND_NULL(qname)if ((qname) != ((void*)0)) { xmlFree((xmlChar *) (qname)); qname
= ((void*)0); }
;
2466 FREE_AND_NULL(msg)if ((msg) != ((void*)0)) { xmlFree((xmlChar *) (msg)); msg = (
(void*)0); }
;
2467}
2468
2469static int
2470xmlSchemaEvalErrorNodeType(xmlSchemaAbstractCtxtPtr actxt,
2471 xmlNodePtr node)
2472{
2473 if (node != NULL((void*)0))
2474 return (node->type);
2475 if ((actxt->type == XML_SCHEMA_CTXT_VALIDATOR2) &&
2476 (((xmlSchemaValidCtxtPtr) actxt)->inode != NULL((void*)0)))
2477 return ( ((xmlSchemaValidCtxtPtr) actxt)->inode->nodeType);
2478 return (-1);
2479}
2480
2481static int
2482xmlSchemaIsGlobalItem(xmlSchemaTypePtr item)
2483{
2484 switch (item->type) {
2485 case XML_SCHEMA_TYPE_COMPLEX:
2486 case XML_SCHEMA_TYPE_SIMPLE:
2487 if (item->flags & XML_SCHEMAS_TYPE_GLOBAL1 << 3)
2488 return(1);
2489 break;
2490 case XML_SCHEMA_TYPE_GROUP:
2491 return (1);
2492 case XML_SCHEMA_TYPE_ELEMENT:
2493 if ( ((xmlSchemaElementPtr) item)->flags &
2494 XML_SCHEMAS_ELEM_GLOBAL1 << 1)
2495 return(1);
2496 break;
2497 case XML_SCHEMA_TYPE_ATTRIBUTE:
2498 if ( ((xmlSchemaAttributePtr) item)->flags &
2499 XML_SCHEMAS_ATTR_GLOBAL1 << 0)
2500 return(1);
2501 break;
2502 /* Note that attribute groups are always global. */
2503 default:
2504 return(1);
2505 }
2506 return (0);
2507}
2508
2509static void
2510xmlSchemaSimpleTypeErr(xmlSchemaAbstractCtxtPtr actxt,
2511 xmlParserErrors error,
2512 xmlNodePtr node,
2513 const xmlChar *value,
2514 xmlSchemaTypePtr type,
2515 int displayValue)
2516{
2517 xmlChar *msg = NULL((void*)0);
2518
2519 xmlSchemaFormatNodeForError(&msg, actxt, node);
2520
2521 if (displayValue || (xmlSchemaEvalErrorNodeType(actxt, node) ==
2522 XML_ATTRIBUTE_NODE))
2523 msg = xmlStrcat(msg, BAD_CAST(xmlChar *) "'%s' is not a valid value of ");
2524 else
2525 msg = xmlStrcat(msg, BAD_CAST(xmlChar *) "The character content is not a valid "
2526 "value of ");
2527
2528 if (! xmlSchemaIsGlobalItem(type))
2529 msg = xmlStrcat(msg, BAD_CAST(xmlChar *) "the local ");
2530 else
2531 msg = xmlStrcat(msg, BAD_CAST(xmlChar *) "the ");
2532
2533 if (WXS_IS_ATOMIC(type)(type->flags & 1 << 8))
2534 msg = xmlStrcat(msg, BAD_CAST(xmlChar *) "atomic type");
2535 else if (WXS_IS_LIST(type)(type->flags & 1 << 6))
2536 msg = xmlStrcat(msg, BAD_CAST(xmlChar *) "list type");
2537 else if (WXS_IS_UNION(type)(type->flags & 1 << 7))
2538 msg = xmlStrcat(msg, BAD_CAST(xmlChar *) "union type");
2539
2540 if (xmlSchemaIsGlobalItem(type)) {
2541 xmlChar *str = NULL((void*)0);
2542 msg = xmlStrcat(msg, BAD_CAST(xmlChar *) " '");
2543 if (type->builtInType != 0) {
2544 msg = xmlStrcat(msg, BAD_CAST(xmlChar *) "xs:");
2545 str = xmlStrdup(type->name);
2546 } else {
2547 const xmlChar *qName = xmlSchemaFormatQName(&str, type->targetNamespace, type->name);
2548 if (!str)
2549 str = xmlStrdup(qName);
2550 }
2551 msg = xmlStrcat(msg, xmlEscapeFormatString(&str));
2552 msg = xmlStrcat(msg, BAD_CAST(xmlChar *) "'");
2553 FREE_AND_NULL(str)if ((str) != ((void*)0)) { xmlFree((xmlChar *) (str)); str = (
(void*)0); }
;
2554 }
2555 msg = xmlStrcat(msg, BAD_CAST(xmlChar *) ".\n");
2556 if (displayValue || (xmlSchemaEvalErrorNodeType(actxt, node) ==
2557 XML_ATTRIBUTE_NODE))
2558 xmlSchemaErr(actxt, error, node, (const char *) msg, value, NULL((void*)0));
2559 else
2560 xmlSchemaErr(actxt, error, node, (const char *) msg, NULL((void*)0), NULL((void*)0));
2561 FREE_AND_NULL(msg)if ((msg) != ((void*)0)) { xmlFree((xmlChar *) (msg)); msg = (
(void*)0); }
2562}
2563
2564static const xmlChar *
2565xmlSchemaFormatErrorNodeQName(xmlChar ** str,
2566 xmlSchemaNodeInfoPtr ni,
2567 xmlNodePtr node)
2568{
2569 if (node != NULL((void*)0)) {
2570 if (node->ns != NULL((void*)0))
2571 return (xmlSchemaFormatQName(str, node->ns->href, node->name));
2572 else
2573 return (xmlSchemaFormatQName(str, NULL((void*)0), node->name));
2574 } else if (ni != NULL((void*)0))
2575 return (xmlSchemaFormatQName(str, ni->nsName, ni->localName));
2576 return (NULL((void*)0));
2577}
2578
2579static void
2580xmlSchemaIllegalAttrErr(xmlSchemaAbstractCtxtPtr actxt,
2581 xmlParserErrors error,
2582 xmlSchemaAttrInfoPtr ni,
2583 xmlNodePtr node)
2584{
2585 xmlChar *msg = NULL((void*)0), *str = NULL((void*)0);
2586
2587 xmlSchemaFormatNodeForError(&msg, actxt, node);
2588 msg = xmlStrcat(msg, BAD_CAST(xmlChar *) "The attribute '%s' is not allowed.\n");
2589 xmlSchemaErr(actxt, error, node, (const char *) msg,
2590 xmlSchemaFormatErrorNodeQName(&str, (xmlSchemaNodeInfoPtr) ni, node),
2591 NULL((void*)0));
2592 FREE_AND_NULL(str)if ((str) != ((void*)0)) { xmlFree((xmlChar *) (str)); str = (
(void*)0); }
2593 FREE_AND_NULL(msg)if ((msg) != ((void*)0)) { xmlFree((xmlChar *) (msg)); msg = (
(void*)0); }
2594}
2595
2596static void LIBXML_ATTR_FORMAT(5,0)__attribute__((__format__(__printf__,5,0)))
2597xmlSchemaComplexTypeErr(xmlSchemaAbstractCtxtPtr actxt,
2598 xmlParserErrors error,
2599 xmlNodePtr node,
2600 xmlSchemaTypePtr type ATTRIBUTE_UNUSED__attribute__((unused)),
2601 const char *message,
2602 int nbval,
2603 int nbneg,
2604 xmlChar **values)
2605{
2606 xmlChar *str = NULL((void*)0), *msg = NULL((void*)0);
2607 xmlChar *localName, *nsName;
2608 const xmlChar *cur, *end;
2609 int i;
2610
2611 xmlSchemaFormatNodeForError(&msg, actxt, node);
2612 msg = xmlStrcat(msg, (const xmlChar *) message);
2613 msg = xmlStrcat(msg, BAD_CAST(xmlChar *) ".");
2614 /*
2615 * Note that is does not make sense to report that we have a
2616 * wildcard here, since the wildcard might be unfolded into
2617 * multiple transitions.
2618 */
2619 if (nbval + nbneg > 0) {
2620 if (nbval + nbneg > 1) {
2621 str = xmlStrdup(BAD_CAST(xmlChar *) " Expected is one of ( ");
2622 } else
2623 str = xmlStrdup(BAD_CAST(xmlChar *) " Expected is ( ");
2624 nsName = NULL((void*)0);
2625
2626 for (i = 0; i < nbval + nbneg; i++) {
2627 cur = values[i];
2628 if (cur == NULL((void*)0))
2629 continue;
2630 if ((cur[0] == 'n') && (cur[1] == 'o') && (cur[2] == 't') &&
2631 (cur[3] == ' ')) {
2632 cur += 4;
2633 str = xmlStrcat(str, BAD_CAST(xmlChar *) "##other");
2634 }
2635 /*
2636 * Get the local name.
2637 */
2638 localName = NULL((void*)0);
2639
2640 end = cur;
2641 if (*end == '*') {
2642 localName = xmlStrdup(BAD_CAST(xmlChar *) "*");
2643 end++;
2644 } else {
2645 while ((*end != 0) && (*end != '|'))
2646 end++;
2647 localName = xmlStrncat(localName, BAD_CAST(xmlChar *) cur, end - cur);
2648 }
2649 if (*end != 0) {
2650 end++;
2651 /*
2652 * Skip "*|*" if they come with negated expressions, since
2653 * they represent the same negated wildcard.
2654 */
2655 if ((nbneg == 0) || (*end != '*') || (*localName != '*')) {
2656 /*
2657 * Get the namespace name.
2658 */
2659 cur = end;
2660 if (*end == '*') {
2661 nsName = xmlStrdup(BAD_CAST(xmlChar *) "{*}");
2662 } else {
2663 while (*end != 0)
2664 end++;
2665
2666 if (i >= nbval)
2667 nsName = xmlStrdup(BAD_CAST(xmlChar *) "{##other:");
2668 else
2669 nsName = xmlStrdup(BAD_CAST(xmlChar *) "{");
2670
2671 nsName = xmlStrncat(nsName, BAD_CAST(xmlChar *) cur, end - cur);
2672 nsName = xmlStrcat(nsName, BAD_CAST(xmlChar *) "}");
2673 }
2674 str = xmlStrcat(str, BAD_CAST(xmlChar *) nsName);
2675 FREE_AND_NULL(nsName)if ((nsName) != ((void*)0)) { xmlFree((xmlChar *) (nsName)); nsName
= ((void*)0); }
2676 } else {
2677 FREE_AND_NULL(localName)if ((localName) != ((void*)0)) { xmlFree((xmlChar *) (localName
)); localName = ((void*)0); }
;
2678 continue;
2679 }
2680 }
2681 str = xmlStrcat(str, BAD_CAST(xmlChar *) localName);
2682 FREE_AND_NULL(localName)if ((localName) != ((void*)0)) { xmlFree((xmlChar *) (localName
)); localName = ((void*)0); }
;
2683
2684 if (i < nbval + nbneg -1)
2685 str = xmlStrcat(str, BAD_CAST(xmlChar *) ", ");
2686 }
2687 str = xmlStrcat(str, BAD_CAST(xmlChar *) " ).\n");
2688 msg = xmlStrcat(msg, xmlEscapeFormatString(&str));
2689 FREE_AND_NULL(str)if ((str) != ((void*)0)) { xmlFree((xmlChar *) (str)); str = (
(void*)0); }
2690 } else
2691 msg = xmlStrcat(msg, BAD_CAST(xmlChar *) "\n");
2692 xmlSchemaErr(actxt, error, node, (const char *) msg, NULL((void*)0), NULL((void*)0));
2693 xmlFree(msg);
2694}
2695
2696static void LIBXML_ATTR_FORMAT(8,0)__attribute__((__format__(__printf__,8,0)))
2697xmlSchemaFacetErr(xmlSchemaAbstractCtxtPtr actxt,
2698 xmlParserErrors error,
2699 xmlNodePtr node,
2700 const xmlChar *value,
2701 unsigned long length,
2702 xmlSchemaTypePtr type,
2703 xmlSchemaFacetPtr facet,
2704 const char *message,
2705 const xmlChar *str1,
2706 const xmlChar *str2)
2707{
2708 xmlChar *str = NULL((void*)0), *msg = NULL((void*)0);
2709 xmlSchemaTypeType facetType;
2710 int nodeType = xmlSchemaEvalErrorNodeType(actxt, node);
2711
2712 xmlSchemaFormatNodeForError(&msg, actxt, node);
2713 if (error == XML_SCHEMAV_CVC_ENUMERATION_VALID) {
2714 facetType = XML_SCHEMA_FACET_ENUMERATION;
2715 /*
2716 * If enumerations are validated, one must not expect the
2717 * facet to be given.
2718 */
2719 } else
2720 facetType = facet->type;
2721 msg = xmlStrcat(msg, BAD_CAST(xmlChar *) "[");
2722 msg = xmlStrcat(msg, BAD_CAST(xmlChar *) "facet '");
2723 msg = xmlStrcat(msg, xmlSchemaFacetTypeToString(facetType));
2724 msg = xmlStrcat(msg, BAD_CAST(xmlChar *) "'] ");
2725 if (message == NULL((void*)0)) {
2726 /*
2727 * Use a default message.
2728 */
2729 if ((facetType == XML_SCHEMA_FACET_LENGTH) ||
2730 (facetType == XML_SCHEMA_FACET_MINLENGTH) ||
2731 (facetType == XML_SCHEMA_FACET_MAXLENGTH)) {
2732
2733 char len[25], actLen[25];
2734
2735 /* FIXME, TODO: What is the max expected string length of the
2736 * this value?
2737 */
2738 if (nodeType == XML_ATTRIBUTE_NODE)
2739 msg = xmlStrcat(msg, BAD_CAST(xmlChar *) "The value '%s' has a length of '%s'; ");
2740 else
2741 msg = xmlStrcat(msg, BAD_CAST(xmlChar *) "The value has a length of '%s'; ");
2742
2743 snprintf(len, 24, "%lu", xmlSchemaGetFacetValueAsULong(facet));
2744 snprintf(actLen, 24, "%lu", length);
2745
2746 if (facetType == XML_SCHEMA_FACET_LENGTH)
2747 msg = xmlStrcat(msg,
2748 BAD_CAST(xmlChar *) "this differs from the allowed length of '%s'.\n");
2749 else if (facetType == XML_SCHEMA_FACET_MAXLENGTH)
2750 msg = xmlStrcat(msg,
2751 BAD_CAST(xmlChar *) "this exceeds the allowed maximum length of '%s'.\n");
2752 else if (facetType == XML_SCHEMA_FACET_MINLENGTH)
2753 msg = xmlStrcat(msg,
2754 BAD_CAST(xmlChar *) "this underruns the allowed minimum length of '%s'.\n");
2755
2756 if (nodeType == XML_ATTRIBUTE_NODE)
2757 xmlSchemaErr3(actxt, error, node, (const char *) msg,
2758 value, (const xmlChar *) actLen, (const xmlChar *) len);
2759 else
2760 xmlSchemaErr(actxt, error, node, (const char *) msg,
2761 (const xmlChar *) actLen, (const xmlChar *) len);
2762
2763 } else if (facetType == XML_SCHEMA_FACET_ENUMERATION) {
2764 msg = xmlStrcat(msg, BAD_CAST(xmlChar *) "The value '%s' is not an element "
2765 "of the set {%s}.\n");
2766 xmlSchemaErr(actxt, error, node, (const char *) msg, value,
2767 xmlSchemaFormatFacetEnumSet(actxt, &str, type));
2768 } else if (facetType == XML_SCHEMA_FACET_PATTERN) {
2769 msg = xmlStrcat(msg, BAD_CAST(xmlChar *) "The value '%s' is not accepted "
2770 "by the pattern '%s'.\n");
2771 xmlSchemaErr(actxt, error, node, (const char *) msg, value,
2772 facet->value);
2773 } else if (facetType == XML_SCHEMA_FACET_MININCLUSIVE) {
2774 msg = xmlStrcat(msg, BAD_CAST(xmlChar *) "The value '%s' is less than the "
2775 "minimum value allowed ('%s').\n");
2776 xmlSchemaErr(actxt, error, node, (const char *) msg, value,
2777 facet->value);
2778 } else if (facetType == XML_SCHEMA_FACET_MAXINCLUSIVE) {
2779 msg = xmlStrcat(msg, BAD_CAST(xmlChar *) "The value '%s' is greater than the "
2780 "maximum value allowed ('%s').\n");
2781 xmlSchemaErr(actxt, error, node, (const char *) msg, value,
2782 facet->value);
2783 } else if (facetType == XML_SCHEMA_FACET_MINEXCLUSIVE) {
2784 msg = xmlStrcat(msg, BAD_CAST(xmlChar *) "The value '%s' must be greater than "
2785 "'%s'.\n");
2786 xmlSchemaErr(actxt, error, node, (const char *) msg, value,
2787 facet->value);
2788 } else if (facetType == XML_SCHEMA_FACET_MAXEXCLUSIVE) {
2789 msg = xmlStrcat(msg, BAD_CAST(xmlChar *) "The value '%s' must be less than "
2790 "'%s'.\n");
2791 xmlSchemaErr(actxt, error, node, (const char *) msg, value,
2792 facet->value);
2793 } else if (facetType == XML_SCHEMA_FACET_TOTALDIGITS) {
2794 msg = xmlStrcat(msg, BAD_CAST(xmlChar *) "The value '%s' has more "
2795 "digits than are allowed ('%s').\n");
2796 xmlSchemaErr(actxt, error, node, (const char*) msg, value,
2797 facet->value);
2798 } else if (facetType == XML_SCHEMA_FACET_FRACTIONDIGITS) {
2799 msg = xmlStrcat(msg, BAD_CAST(xmlChar *) "The value '%s' has more fractional "
2800 "digits than are allowed ('%s').\n");
2801 xmlSchemaErr(actxt, error, node, (const char*) msg, value,
2802 facet->value);
2803 } else if (nodeType == XML_ATTRIBUTE_NODE) {
2804 msg = xmlStrcat(msg, BAD_CAST(xmlChar *) "The value '%s' is not facet-valid.\n");
2805 xmlSchemaErr(actxt, error, node, (const char *) msg, value, NULL((void*)0));
2806 } else {
2807 msg = xmlStrcat(msg, BAD_CAST(xmlChar *) "The value is not facet-valid.\n");
2808 xmlSchemaErr(actxt, error, node, (const char *) msg, NULL((void*)0), NULL((void*)0));
2809 }
2810 } else {
2811 msg = xmlStrcat(msg, (const xmlChar *) message);
2812 msg = xmlStrcat(msg, BAD_CAST(xmlChar *) ".\n");
2813 xmlSchemaErr(actxt, error, node, (const char *) msg, str1, str2);
2814 }
2815 FREE_AND_NULL(str)if ((str) != ((void*)0)) { xmlFree((xmlChar *) (str)); str = (
(void*)0); }
2816 xmlFree(msg);
2817}
2818
2819#define VERROR(err, type, msg)xmlSchemaCustomErr((xmlSchemaAbstractCtxtPtr) vctxt, err, ((void
*)0), type, msg, ((void*)0), ((void*)0));
\
2820 xmlSchemaCustomErr(ACTXT_CAST(xmlSchemaAbstractCtxtPtr) vctxt, err, NULL((void*)0), type, msg, NULL((void*)0), NULL((void*)0));
2821
2822#define VERROR_INT(func, msg)xmlSchemaInternalErr((xmlSchemaAbstractCtxtPtr) vctxt, func, msg
);
xmlSchemaInternalErr(ACTXT_CAST(xmlSchemaAbstractCtxtPtr) vctxt, func, msg);
2823
2824#define PERROR_INT(func, msg)xmlSchemaInternalErr((xmlSchemaAbstractCtxtPtr) pctxt, func, msg
);
xmlSchemaInternalErr(ACTXT_CAST(xmlSchemaAbstractCtxtPtr) pctxt, func, msg);
2825#define PERROR_INT2(func, msg)xmlSchemaInternalErr((xmlSchemaAbstractCtxtPtr) ctxt, func, msg
);
xmlSchemaInternalErr(ACTXT_CAST(xmlSchemaAbstractCtxtPtr) ctxt, func, msg);
2826
2827#define AERROR_INT(func, msg)xmlSchemaInternalErr(actxt, func, msg); xmlSchemaInternalErr(actxt, func, msg);
2828
2829
2830/**
2831 * xmlSchemaPMissingAttrErr:
2832 * @ctxt: the schema validation context
2833 * @ownerItem: the owner as a schema object
2834 * @ownerElem: the owner as an element node
2835 * @node: the parent element node of the missing attribute node
2836 * @type: the corresponding type of the attribute node
2837 *
2838 * Reports an illegal attribute.
2839 */
2840static void
2841xmlSchemaPMissingAttrErr(xmlSchemaParserCtxtPtr ctxt,
2842 xmlParserErrors error,
2843 xmlSchemaBasicItemPtr ownerItem,
2844 xmlNodePtr ownerElem,
2845 const char *name,
2846 const char *message)
2847{
2848 xmlChar *des = NULL((void*)0);
2849
2850 xmlSchemaFormatItemForReport(&des, NULL((void*)0), ownerItem, ownerElem);
2851
2852 if (message != NULL((void*)0))
2853 xmlSchemaPErr(ctxt, ownerElem, error, "%s: %s.\n", BAD_CAST(xmlChar *) des, BAD_CAST(xmlChar *) message);
2854 else
2855 xmlSchemaPErr(ctxt, ownerElem, error,
2856 "%s: The attribute '%s' is required but missing.\n",
2857 BAD_CAST(xmlChar *) des, BAD_CAST(xmlChar *) name);
2858 FREE_AND_NULL(des)if ((des) != ((void*)0)) { xmlFree((xmlChar *) (des)); des = (
(void*)0); }
;
2859}
2860
2861
2862/**
2863 * xmlSchemaPResCompAttrErr:
2864 * @ctxt: the schema validation context
2865 * @error: the error code
2866 * @ownerItem: the owner as a schema object
2867 * @ownerElem: the owner as an element node
2868 * @name: the name of the attribute holding the QName
2869 * @refName: the referenced local name
2870 * @refURI: the referenced namespace URI
2871 * @message: optional message
2872 *
2873 * Used to report QName attribute values that failed to resolve
2874 * to schema components.
2875 */
2876static void
2877xmlSchemaPResCompAttrErr(xmlSchemaParserCtxtPtr ctxt,
2878 xmlParserErrors error,
2879 xmlSchemaBasicItemPtr ownerItem,
2880 xmlNodePtr ownerElem,
2881 const char *name,
2882 const xmlChar *refName,
2883 const xmlChar *refURI,
2884 xmlSchemaTypeType refType,
2885 const char *refTypeStr)
2886{
2887 xmlChar *des = NULL((void*)0), *strA = NULL((void*)0);
2888
2889 xmlSchemaFormatItemForReport(&des, NULL((void*)0), ownerItem, ownerElem);
2890 if (refTypeStr == NULL((void*)0))
2891 refTypeStr = (const char *) xmlSchemaItemTypeToStr(refType);
2892 xmlSchemaPErrExt(ctxt, ownerElem, error,
2893 NULL((void*)0), NULL((void*)0), NULL((void*)0),
2894 "%s, attribute '%s': The QName value '%s' does not resolve to a(n) "
2895 "%s.\n", BAD_CAST(xmlChar *) des, BAD_CAST(xmlChar *) name,
2896 xmlSchemaFormatQName(&strA, refURI, refName),
2897 BAD_CAST(xmlChar *) refTypeStr, NULL((void*)0));
2898 FREE_AND_NULL(des)if ((des) != ((void*)0)) { xmlFree((xmlChar *) (des)); des = (
(void*)0); }
2899 FREE_AND_NULL(strA)if ((strA) != ((void*)0)) { xmlFree((xmlChar *) (strA)); strA
= ((void*)0); }
2900}
2901
2902/**
2903 * xmlSchemaPCustomAttrErr:
2904 * @ctxt: the schema parser context
2905 * @error: the error code
2906 * @ownerDes: the designation of the owner
2907 * @ownerItem: the owner as a schema object
2908 * @attr: the illegal attribute node
2909 *
2910 * Reports an illegal attribute during the parse.
2911 */
2912static void
2913xmlSchemaPCustomAttrErr(xmlSchemaParserCtxtPtr ctxt,
2914 xmlParserErrors error,
2915 xmlChar **ownerDes,
2916 xmlSchemaBasicItemPtr ownerItem,
2917 xmlAttrPtr attr,
2918 const char *msg)
2919{
2920 xmlChar *des = NULL((void*)0);
2921
2922 if (ownerDes == NULL((void*)0))
2923 xmlSchemaFormatItemForReport(&des, NULL((void*)0), ownerItem, attr->parent);
2924 else if (*ownerDes == NULL((void*)0)) {
2925 xmlSchemaFormatItemForReport(ownerDes, NULL((void*)0), ownerItem, attr->parent);
2926 des = *ownerDes;
2927 } else
2928 des = *ownerDes;
2929 if (attr == NULL((void*)0)) {
2930 xmlSchemaPErrExt(ctxt, NULL((void*)0), error, NULL((void*)0), NULL((void*)0), NULL((void*)0),
2931 "%s, attribute '%s': %s.\n",
2932 BAD_CAST(xmlChar *) des, (const xmlChar *) "Unknown",
2933 (const xmlChar *) msg, NULL((void*)0), NULL((void*)0));
2934 } else {
2935 xmlSchemaPErrExt(ctxt, (xmlNodePtr) attr, error, NULL((void*)0), NULL((void*)0), NULL((void*)0),
2936 "%s, attribute '%s': %s.\n",
2937 BAD_CAST(xmlChar *) des, attr->name, (const xmlChar *) msg, NULL((void*)0), NULL((void*)0));
2938 }
2939 if (ownerDes == NULL((void*)0))
2940 FREE_AND_NULL(des)if ((des) != ((void*)0)) { xmlFree((xmlChar *) (des)); des = (
(void*)0); }
;
2941}
2942
2943/**
2944 * xmlSchemaPIllegalAttrErr:
2945 * @ctxt: the schema parser context
2946 * @error: the error code
2947 * @ownerItem: the attribute's owner item
2948 * @attr: the illegal attribute node
2949 *
2950 * Reports an illegal attribute during the parse.
2951 */
2952static void
2953xmlSchemaPIllegalAttrErr(xmlSchemaParserCtxtPtr ctxt,
2954 xmlParserErrors error,
2955 xmlSchemaBasicItemPtr ownerComp ATTRIBUTE_UNUSED__attribute__((unused)),
2956 xmlAttrPtr attr)
2957{
2958 xmlChar *strA = NULL((void*)0), *strB = NULL((void*)0);
2959
2960 xmlSchemaFormatNodeForError(&strA, ACTXT_CAST(xmlSchemaAbstractCtxtPtr) ctxt, attr->parent);
2961 xmlSchemaErr4(ACTXT_CAST(xmlSchemaAbstractCtxtPtr) ctxt, error, (xmlNodePtr) attr,
2962 "%sThe attribute '%s' is not allowed.\n", BAD_CAST(xmlChar *) strA,
2963 xmlSchemaFormatQNameNs(&strB, attr->ns, attr->name),
2964 NULL((void*)0), NULL((void*)0));
2965 FREE_AND_NULL(strA)if ((strA) != ((void*)0)) { xmlFree((xmlChar *) (strA)); strA
= ((void*)0); }
;
2966 FREE_AND_NULL(strB)if ((strB) != ((void*)0)) { xmlFree((xmlChar *) (strB)); strB
= ((void*)0); }
;
2967}
2968
2969/**
2970 * xmlSchemaPCustomErr:
2971 * @ctxt: the schema parser context
2972 * @error: the error code
2973 * @itemDes: the designation of the schema item
2974 * @item: the schema item
2975 * @itemElem: the node of the schema item
2976 * @message: the error message
2977 * @str1: an optional param for the error message
2978 * @str2: an optional param for the error message
2979 * @str3: an optional param for the error message
2980 *
2981 * Reports an error during parsing.
2982 */
2983static void LIBXML_ATTR_FORMAT(5,0)__attribute__((__format__(__printf__,5,0)))
2984xmlSchemaPCustomErrExt(xmlSchemaParserCtxtPtr ctxt,
2985 xmlParserErrors error,
2986 xmlSchemaBasicItemPtr item,
2987 xmlNodePtr itemElem,
2988 const char *message,
2989 const xmlChar *str1,
2990 const xmlChar *str2,
2991 const xmlChar *str3)
2992{
2993 xmlChar *des = NULL((void*)0), *msg = NULL((void*)0);
2994
2995 xmlSchemaFormatItemForReport(&des, NULL((void*)0), item, itemElem);
2996 msg = xmlStrdup(BAD_CAST(xmlChar *) "%s: ");
2997 msg = xmlStrcat(msg, (const xmlChar *) message);
2998 msg = xmlStrcat(msg, BAD_CAST(xmlChar *) ".\n");
2999 if ((itemElem == NULL((void*)0)) && (item != NULL((void*)0)))
3000 itemElem = WXS_ITEM_NODE(item)xmlSchemaGetComponentNode((xmlSchemaBasicItemPtr) (item));
3001 xmlSchemaPErrExt(ctxt, itemElem, error, NULL((void*)0), NULL((void*)0), NULL((void*)0),
3002 (const char *) msg, BAD_CAST(xmlChar *) des, str1, str2, str3, NULL((void*)0));
3003 FREE_AND_NULL(des)if ((des) != ((void*)0)) { xmlFree((xmlChar *) (des)); des = (
(void*)0); }
;
3004 FREE_AND_NULL(msg)if ((msg) != ((void*)0)) { xmlFree((xmlChar *) (msg)); msg = (
(void*)0); }
;
3005}
3006
3007/**
3008 * xmlSchemaPCustomErr:
3009 * @ctxt: the schema parser context
3010 * @error: the error code
3011 * @itemDes: the designation of the schema item
3012 * @item: the schema item
3013 * @itemElem: the node of the schema item
3014 * @message: the error message
3015 * @str1: the optional param for the error message
3016 *
3017 * Reports an error during parsing.
3018 */
3019static void LIBXML_ATTR_FORMAT(5,0)__attribute__((__format__(__printf__,5,0)))
3020xmlSchemaPCustomErr(xmlSchemaParserCtxtPtr ctxt,
3021 xmlParserErrors error,
3022 xmlSchemaBasicItemPtr item,
3023 xmlNodePtr itemElem,
3024 const char *message,
3025 const xmlChar *str1)
3026{
3027 xmlSchemaPCustomErrExt(ctxt, error, item, itemElem, message,
3028 str1, NULL((void*)0), NULL((void*)0));
3029}
3030
3031/**
3032 * xmlSchemaPAttrUseErr:
3033 * @ctxt: the schema parser context
3034 * @error: the error code
3035 * @itemDes: the designation of the schema type
3036 * @item: the schema type
3037 * @itemElem: the node of the schema type
3038 * @attr: the invalid schema attribute
3039 * @message: the error message
3040 * @str1: the optional param for the error message
3041 *
3042 * Reports an attribute use error during parsing.
3043 */
3044static void LIBXML_ATTR_FORMAT(6,0)__attribute__((__format__(__printf__,6,0)))
3045xmlSchemaPAttrUseErr4(xmlSchemaParserCtxtPtr ctxt,
3046 xmlParserErrors error,
3047 xmlNodePtr node,
3048 xmlSchemaBasicItemPtr ownerItem,
3049 const xmlSchemaAttributeUsePtr attruse,
3050 const char *message,
3051 const xmlChar *str1, const xmlChar *str2,
3052 const xmlChar *str3,const xmlChar *str4)
3053{
3054 xmlChar *str = NULL((void*)0), *msg = NULL((void*)0);
3055
3056 xmlSchemaFormatItemForReport(&msg, NULL((void*)0), ownerItem, NULL((void*)0));
3057 msg = xmlStrcat(msg, BAD_CAST(xmlChar *) ", ");
3058 msg = xmlStrcat(msg,
3059 BAD_CAST(xmlChar *) xmlSchemaFormatItemForReport(&str, NULL((void*)0),
3060 WXS_BASIC_CAST(xmlSchemaBasicItemPtr) attruse, NULL((void*)0)));
3061 FREE_AND_NULL(str)if ((str) != ((void*)0)) { xmlFree((xmlChar *) (str)); str = (
(void*)0); }
;
3062 msg = xmlStrcat(msg, BAD_CAST(xmlChar *) ": ");
3063 msg = xmlStrcat(msg, (const xmlChar *) message);
3064 msg = xmlStrcat(msg, BAD_CAST(xmlChar *) ".\n");
3065 xmlSchemaErr4(ACTXT_CAST(xmlSchemaAbstractCtxtPtr) ctxt, error, node,
3066 (const char *) msg, str1, str2, str3, str4);
3067 xmlFree(msg);
3068}
3069
3070/**
3071 * xmlSchemaPIllegalFacetAtomicErr:
3072 * @ctxt: the schema parser context
3073 * @error: the error code
3074 * @type: the schema type
3075 * @baseType: the base type of type
3076 * @facet: the illegal facet
3077 *
3078 * Reports an illegal facet for atomic simple types.
3079 */
3080static void
3081xmlSchemaPIllegalFacetAtomicErr(xmlSchemaParserCtxtPtr ctxt,
3082 xmlParserErrors error,
3083 xmlSchemaTypePtr type,
3084 xmlSchemaTypePtr baseType,
3085 xmlSchemaFacetPtr facet)
3086{
3087 xmlChar *des = NULL((void*)0), *strT = NULL((void*)0);
3088
3089 xmlSchemaFormatItemForReport(&des, NULL((void*)0), WXS_BASIC_CAST(xmlSchemaBasicItemPtr) type, type->node);
3090 xmlSchemaPErrExt(ctxt, type->node, error, NULL((void*)0), NULL((void*)0), NULL((void*)0),
3091 "%s: The facet '%s' is not allowed on types derived from the "
3092 "type %s.\n",
3093 BAD_CAST(xmlChar *) des, xmlSchemaFacetTypeToString(facet->type),
3094 xmlSchemaFormatItemForReport(&strT, NULL((void*)0), WXS_BASIC_CAST(xmlSchemaBasicItemPtr) baseType, NULL((void*)0)),
3095 NULL((void*)0), NULL((void*)0));
3096 FREE_AND_NULL(des)if ((des) != ((void*)0)) { xmlFree((xmlChar *) (des)); des = (
(void*)0); }
;
3097 FREE_AND_NULL(strT)if ((strT) != ((void*)0)) { xmlFree((xmlChar *) (strT)); strT
= ((void*)0); }
;
3098}
3099
3100/**
3101 * xmlSchemaPIllegalFacetListUnionErr:
3102 * @ctxt: the schema parser context
3103 * @error: the error code
3104 * @itemDes: the designation of the schema item involved
3105 * @item: the schema item involved
3106 * @facet: the illegal facet
3107 *
3108 * Reports an illegal facet for <list> and <union>.
3109 */
3110static void
3111xmlSchemaPIllegalFacetListUnionErr(xmlSchemaParserCtxtPtr ctxt,
3112 xmlParserErrors error,
3113 xmlSchemaTypePtr type,
3114 xmlSchemaFacetPtr facet)
3115{
3116 xmlChar *des = NULL((void*)0);
3117
3118 xmlSchemaFormatItemForReport(&des, NULL((void*)0), WXS_BASIC_CAST(xmlSchemaBasicItemPtr) type,
3119 type->node);
3120 xmlSchemaPErr(ctxt, type->node, error,
3121 "%s: The facet '%s' is not allowed.\n",
3122 BAD_CAST(xmlChar *) des, xmlSchemaFacetTypeToString(facet->type));
3123 FREE_AND_NULL(des)if ((des) != ((void*)0)) { xmlFree((xmlChar *) (des)); des = (
(void*)0); }
;
3124}
3125
3126/**
3127 * xmlSchemaPMutualExclAttrErr:
3128 * @ctxt: the schema validation context
3129 * @error: the error code
3130 * @elemDes: the designation of the parent element node
3131 * @attr: the bad attribute node
3132 * @type: the corresponding type of the attribute node
3133 *
3134 * Reports an illegal attribute.
3135 */
3136static void
3137xmlSchemaPMutualExclAttrErr(xmlSchemaParserCtxtPtr ctxt,
3138 xmlParserErrors error,
3139 xmlSchemaBasicItemPtr ownerItem,
3140 xmlAttrPtr attr,
3141 const char *name1,
3142 const char *name2)
3143{
3144 xmlChar *des = NULL((void*)0);
3145
3146 xmlSchemaFormatItemForReport(&des, NULL((void*)0), WXS_BASIC_CAST(xmlSchemaBasicItemPtr) ownerItem, attr->parent);
3147 xmlSchemaPErrExt(ctxt, (xmlNodePtr) attr, error, NULL((void*)0), NULL((void*)0), NULL((void*)0),
3148 "%s: The attributes '%s' and '%s' are mutually exclusive.\n",
3149 BAD_CAST(xmlChar *) des, BAD_CAST(xmlChar *) name1, BAD_CAST(xmlChar *) name2, NULL((void*)0), NULL((void*)0));
3150 FREE_AND_NULL(des)if ((des) != ((void*)0)) { xmlFree((xmlChar *) (des)); des = (
(void*)0); }
;
3151}
3152
3153/**
3154 * xmlSchemaPSimpleTypeErr:
3155 * @ctxt: the schema validation context
3156 * @error: the error code
3157 * @type: the type specifier
3158 * @ownerItem: the schema object if existent
3159 * @node: the validated node
3160 * @value: the validated value
3161 *
3162 * Reports a simple type validation error.
3163 * TODO: Should this report the value of an element as well?
3164 */
3165static void LIBXML_ATTR_FORMAT(8,0)__attribute__((__format__(__printf__,8,0)))
3166xmlSchemaPSimpleTypeErr(xmlSchemaParserCtxtPtr ctxt,
3167 xmlParserErrors error,
3168 xmlSchemaBasicItemPtr ownerItem ATTRIBUTE_UNUSED__attribute__((unused)),
3169 xmlNodePtr node,
3170 xmlSchemaTypePtr type,
3171 const char *expected,
3172 const xmlChar *value,
3173 const char *message,
3174 const xmlChar *str1,
3175 const xmlChar *str2)
3176{
3177 xmlChar *msg = NULL((void*)0);
3178
3179 xmlSchemaFormatNodeForError(&msg, ACTXT_CAST(xmlSchemaAbstractCtxtPtr) ctxt, node);
3180 if (message == NULL((void*)0)) {
3181 /*
3182 * Use default messages.
3183 */
3184 if (type != NULL((void*)0)) {
3185 if (node->type == XML_ATTRIBUTE_NODE)
3186 msg = xmlStrcat(msg, BAD_CAST(xmlChar *) "'%s' is not a valid value of ");
3187 else
3188 msg = xmlStrcat(msg, BAD_CAST(xmlChar *) "The character content is not a "
3189 "valid value of ");
3190 if (! xmlSchemaIsGlobalItem(type))
3191 msg = xmlStrcat(msg, BAD_CAST(xmlChar *) "the local ");
3192 else
3193 msg = xmlStrcat(msg, BAD_CAST(xmlChar *) "the ");
3194
3195 if (WXS_IS_ATOMIC(type)(type->flags & 1 << 8))
3196 msg = xmlStrcat(msg, BAD_CAST(xmlChar *) "atomic type");
3197 else if (WXS_IS_LIST(type)(type->flags & 1 << 6))
3198 msg = xmlStrcat(msg, BAD_CAST(xmlChar *) "list type");
3199 else if (WXS_IS_UNION(type)(type->flags & 1 << 7))
3200 msg = xmlStrcat(msg, BAD_CAST(xmlChar *) "union type");
3201
3202 if (xmlSchemaIsGlobalItem(type)) {
3203 xmlChar *str = NULL((void*)0);
3204 msg = xmlStrcat(msg, BAD_CAST(xmlChar *) " '");
3205 if (type->builtInType != 0) {
3206 msg = xmlStrcat(msg, BAD_CAST(xmlChar *) "xs:");
3207 str = xmlStrdup(type->name);
3208 } else {
3209 const xmlChar *qName = xmlSchemaFormatQName(&str, type->targetNamespace, type->name);
3210 if (!str)
3211 str = xmlStrdup(qName);
3212 }
3213 msg = xmlStrcat(msg, xmlEscapeFormatString(&str));
3214 msg = xmlStrcat(msg, BAD_CAST(xmlChar *) "'.");
3215 FREE_AND_NULL(str)if ((str) != ((void*)0)) { xmlFree((xmlChar *) (str)); str = (
(void*)0); }
;
3216 }
3217 } else {
3218 if (node->type == XML_ATTRIBUTE_NODE)
3219 msg = xmlStrcat(msg, BAD_CAST(xmlChar *) "The value '%s' is not valid.");
3220 else
3221 msg = xmlStrcat(msg, BAD_CAST(xmlChar *) "The character content is not "
3222 "valid.");
3223 }
3224 if (expected) {
3225 xmlChar *expectedEscaped = xmlCharStrdup(expected);
3226 msg = xmlStrcat(msg, BAD_CAST(xmlChar *) " Expected is '");
3227 msg = xmlStrcat(msg, xmlEscapeFormatString(&expectedEscaped));
3228 FREE_AND_NULL(expectedEscaped)if ((expectedEscaped) != ((void*)0)) { xmlFree((xmlChar *) (expectedEscaped
)); expectedEscaped = ((void*)0); }
;
3229 msg = xmlStrcat(msg, BAD_CAST(xmlChar *) "'.\n");
3230 } else
3231 msg = xmlStrcat(msg, BAD_CAST(xmlChar *) "\n");
3232 if (node->type == XML_ATTRIBUTE_NODE)
3233 xmlSchemaPErr(ctxt, node, error, (const char *) msg, value, NULL((void*)0));
3234 else
3235 xmlSchemaPErr(ctxt, node, error, (const char *) msg, NULL((void*)0), NULL((void*)0));
3236 } else {
3237 msg = xmlStrcat(msg, BAD_CAST(xmlChar *) message);
3238 msg = xmlStrcat(msg, BAD_CAST(xmlChar *) ".\n");
3239 xmlSchemaPErrExt(ctxt, node, error, NULL((void*)0), NULL((void*)0), NULL((void*)0),
3240 (const char*) msg, str1, str2, NULL((void*)0), NULL((void*)0), NULL((void*)0));
3241 }
3242 /* Cleanup. */
3243 FREE_AND_NULL(msg)if ((msg) != ((void*)0)) { xmlFree((xmlChar *) (msg)); msg = (
(void*)0); }
3244}
3245
3246/**
3247 * xmlSchemaPContentErr:
3248 * @ctxt: the schema parser context
3249 * @error: the error code
3250 * @ownerItem: the owner item of the holder of the content
3251 * @ownerElem: the node of the holder of the content
3252 * @child: the invalid child node
3253 * @message: the optional error message
3254 * @content: the optional string describing the correct content
3255 *
3256 * Reports an error concerning the content of a schema element.
3257 */
3258static void
3259xmlSchemaPContentErr(xmlSchemaParserCtxtPtr ctxt,
3260 xmlParserErrors error,
3261 xmlSchemaBasicItemPtr ownerItem,
3262 xmlNodePtr ownerElem,
3263 xmlNodePtr child,
3264 const char *message,
3265 const char *content)
3266{
3267 xmlChar *des = NULL((void*)0);
3268
3269 xmlSchemaFormatItemForReport(&des, NULL((void*)0), ownerItem, ownerElem);
3270 if (message != NULL((void*)0))
3271 xmlSchemaPErr2(ctxt, ownerElem, child, error,
3272 "%s: %s.\n",
3273 BAD_CAST(xmlChar *) des, BAD_CAST(xmlChar *) message);
3274 else {
3275 if (content != NULL((void*)0)) {
3276 xmlSchemaPErr2(ctxt, ownerElem, child, error,
3277 "%s: The content is not valid. Expected is %s.\n",
3278 BAD_CAST(xmlChar *) des, BAD_CAST(xmlChar *) content);
3279 } else {
3280 xmlSchemaPErr2(ctxt, ownerElem, child, error,
3281 "%s: The content is not valid.\n",
3282 BAD_CAST(xmlChar *) des, NULL((void*)0));
3283 }
3284 }
3285 FREE_AND_NULL(des)if ((des) != ((void*)0)) { xmlFree((xmlChar *) (des)); des = (
(void*)0); }
3286}
3287
3288/************************************************************************
3289 * *
3290 * Streamable error functions *
3291 * *
3292 ************************************************************************/
3293
3294
3295
3296
3297/************************************************************************
3298 * *
3299 * Validation helper functions *
3300 * *
3301 ************************************************************************/
3302
3303
3304/************************************************************************
3305 * *
3306 * Allocation functions *
3307 * *
3308 ************************************************************************/
3309
3310/**
3311 * xmlSchemaNewSchemaForParserCtxt:
3312 * @ctxt: a schema validation context
3313 *
3314 * Allocate a new Schema structure.
3315 *
3316 * Returns the newly allocated structure or NULL in case or error
3317 */
3318static xmlSchemaPtr
3319xmlSchemaNewSchema(xmlSchemaParserCtxtPtr ctxt)
3320{
3321 xmlSchemaPtr ret;
3322
3323 ret = (xmlSchemaPtr) xmlMalloc(sizeof(xmlSchema));
3324 if (ret == NULL((void*)0)) {
3325 xmlSchemaPErrMemory(ctxt, "allocating schema", NULL((void*)0));
3326 return (NULL((void*)0));
3327 }
3328 memset(ret, 0, sizeof(xmlSchema));
3329 ret->dict = ctxt->dict;
3330 xmlDictReference(ret->dict);
3331
3332 return (ret);
3333}
3334
3335/**
3336 * xmlSchemaNewFacet:
3337 *
3338 * Allocate a new Facet structure.
3339 *
3340 * Returns the newly allocated structure or NULL in case or error
3341 */
3342xmlSchemaFacetPtr
3343xmlSchemaNewFacet(void)
3344{
3345 xmlSchemaFacetPtr ret;
3346
3347 ret = (xmlSchemaFacetPtr) xmlMalloc(sizeof(xmlSchemaFacet));
3348 if (ret == NULL((void*)0)) {
3349 return (NULL((void*)0));
3350 }
3351 memset(ret, 0, sizeof(xmlSchemaFacet));
3352
3353 return (ret);
3354}
3355
3356/**
3357 * xmlSchemaNewAnnot:
3358 * @ctxt: a schema validation context
3359 * @node: a node
3360 *
3361 * Allocate a new annotation structure.
3362 *
3363 * Returns the newly allocated structure or NULL in case or error
3364 */
3365static xmlSchemaAnnotPtr
3366xmlSchemaNewAnnot(xmlSchemaParserCtxtPtr ctxt, xmlNodePtr node)
3367{
3368 xmlSchemaAnnotPtr ret;
3369
3370 ret = (xmlSchemaAnnotPtr) xmlMalloc(sizeof(xmlSchemaAnnot));
3371 if (ret == NULL((void*)0)) {
3372 xmlSchemaPErrMemory(ctxt, "allocating annotation", node);
3373 return (NULL((void*)0));
3374 }
3375 memset(ret, 0, sizeof(xmlSchemaAnnot));
3376 ret->content = node;
3377 return (ret);
3378}
3379
3380static xmlSchemaItemListPtr
3381xmlSchemaItemListCreate(void)
3382{
3383 xmlSchemaItemListPtr ret;
3384
3385 ret = xmlMalloc(sizeof(xmlSchemaItemList));
3386 if (ret == NULL((void*)0)) {
3387 xmlSchemaPErrMemory(NULL((void*)0),
3388 "allocating an item list structure", NULL((void*)0));
3389 return (NULL((void*)0));
3390 }
3391 memset(ret, 0, sizeof(xmlSchemaItemList));
3392 return (ret);
3393}
3394
3395static void
3396xmlSchemaItemListClear(xmlSchemaItemListPtr list)
3397{
3398 if (list->items != NULL((void*)0)) {
3399 xmlFree(list->items);
3400 list->items = NULL((void*)0);
3401 }
3402 list->nbItems = 0;
3403 list->sizeItems = 0;
3404}
3405
3406static int
3407xmlSchemaItemListAdd(xmlSchemaItemListPtr list, void *item)
3408{
3409 if (list->sizeItems <= list->nbItems) {
3410 void **tmp;
3411 size_t newSize = list->sizeItems == 0 ? 20 : list->sizeItems * 2;
3412
3413 tmp = (void **) xmlRealloc(list->items, newSize * sizeof(void *));
3414 if (tmp == NULL((void*)0)) {
3415 xmlSchemaPErrMemory(NULL((void*)0), "growing item list", NULL((void*)0));
3416 return(-1);
3417 }
3418 list->items = tmp;
3419 list->sizeItems = newSize;
3420 }
3421 list->items[list->nbItems++] = item;
3422 return(0);
3423}
3424
3425static int
3426xmlSchemaItemListAddSize(xmlSchemaItemListPtr list,
3427 int initialSize,
3428 void *item)
3429{
3430 if (list->items == NULL((void*)0)) {
3431 if (initialSize <= 0)
3432 initialSize = 1;
3433 list->items = (void **) xmlMalloc(
3434 initialSize * sizeof(void *));
3435 if (list->items == NULL((void*)0)) {
3436 xmlSchemaPErrMemory(NULL((void*)0), "allocating new item list", NULL((void*)0));
3437 return(-1);
3438 }
3439 list->sizeItems = initialSize;
3440 } else if (list->sizeItems <= list->nbItems) {
3441 void **tmp;
3442
3443 list->sizeItems *= 2;
3444 tmp = (void **) xmlRealloc(list->items,
3445 list->sizeItems * sizeof(void *));
3446 if (tmp == NULL((void*)0)) {
3447 xmlSchemaPErrMemory(NULL((void*)0), "growing item list", NULL((void*)0));
3448 list->sizeItems /= 2;
3449 return(-1);
3450 }
3451 list->items = tmp;
3452 }
3453 list->items[list->nbItems++] = item;
3454 return(0);
3455}
3456
3457static int
3458xmlSchemaItemListInsert(xmlSchemaItemListPtr list, void *item, int idx)
3459{
3460 if (list->sizeItems <= list->nbItems) {
3461 void **tmp;
3462 size_t newSize = list->sizeItems == 0 ? 20 : list->sizeItems * 2;
3463
3464 tmp = (void **) xmlRealloc(list->items, newSize * sizeof(void *));
3465 if (tmp == NULL((void*)0)) {
3466 xmlSchemaPErrMemory(NULL((void*)0), "growing item list", NULL((void*)0));
3467 return(-1);
3468 }
3469 list->items = tmp;
3470 list->sizeItems = newSize;
3471 }
3472 /*
3473 * Just append if the index is greater/equal than the item count.
3474 */
3475 if (idx >= list->nbItems) {
3476 list->items[list->nbItems++] = item;
3477 } else {
3478 int i;
3479 for (i = list->nbItems; i > idx; i--)
3480 list->items[i] = list->items[i-1];
3481 list->items[idx] = item;
3482 list->nbItems++;
3483 }
3484 return(0);
3485}
3486
3487#if 0 /* enable if ever needed */
3488static int
3489xmlSchemaItemListInsertSize(xmlSchemaItemListPtr list,
3490 int initialSize,
3491 void *item,
3492 int idx)
3493{
3494 if (list->items == NULL((void*)0)) {
3495 if (initialSize <= 0)
3496 initialSize = 1;
3497 list->items = (void **) xmlMalloc(
3498 initialSize * sizeof(void *));
3499 if (list->items == NULL((void*)0)) {
3500 xmlSchemaPErrMemory(NULL((void*)0), "allocating new item list", NULL((void*)0));
3501 return(-1);
3502 }
3503 list->sizeItems = initialSize;
3504 } else if (list->sizeItems <= list->nbItems) {
3505 list->sizeItems *= 2;
3506 list->items = (void **) xmlRealloc(list->items,
3507 list->sizeItems * sizeof(void *));
3508 if (list->items == NULL((void*)0)) {
3509 xmlSchemaPErrMemory(NULL((void*)0), "growing item list", NULL((void*)0));
3510 list->sizeItems = 0;
3511 return(-1);
3512 }
3513 }
3514 /*
3515 * Just append if the index is greater/equal than the item count.
3516 */
3517 if (idx >= list->nbItems) {
3518 list->items[list->nbItems++] = item;
3519 } else {
3520 int i;
3521 for (i = list->nbItems; i > idx; i--)
3522 list->items[i] = list->items[i-1];
3523 list->items[idx] = item;
3524 list->nbItems++;
3525 }
3526 return(0);
3527}
3528#endif
3529
3530static int
3531xmlSchemaItemListRemove(xmlSchemaItemListPtr list, int idx)
3532{
3533 int i;
3534 if ((list->items == NULL((void*)0)) || (idx >= list->nbItems)) {
3535 xmlSchemaPSimpleErr("Internal error: xmlSchemaItemListRemove, "
3536 "index error.\n");
3537 return(-1);
3538 }
3539
3540 if (list->nbItems == 1) {
3541 /* TODO: Really free the list? */
3542 xmlFree(list->items);
3543 list->items = NULL((void*)0);
3544 list->nbItems = 0;
3545 list->sizeItems = 0;
3546 } else if (list->nbItems -1 == idx) {
3547 list->nbItems--;
3548 } else {
3549 for (i = idx; i < list->nbItems -1; i++)
3550 list->items[i] = list->items[i+1];
3551 list->nbItems--;
3552 }
3553 return(0);
3554}
3555
3556/**
3557 * xmlSchemaItemListFree:
3558 * @annot: a schema type structure
3559 *
3560 * Deallocate a annotation structure
3561 */
3562static void
3563xmlSchemaItemListFree(xmlSchemaItemListPtr list)
3564{
3565 if (list == NULL((void*)0))
3566 return;
3567 if (list->items != NULL((void*)0))
3568 xmlFree(list->items);
3569 xmlFree(list);
3570}
3571
3572static void
3573xmlSchemaBucketFree(xmlSchemaBucketPtr bucket)
3574{
3575 if (bucket == NULL((void*)0))
3576 return;
3577 if (bucket->globals != NULL((void*)0)) {
3578 xmlSchemaComponentListFree(bucket->globals);
3579 xmlSchemaItemListFree(bucket->globals);
3580 }
3581 if (bucket->locals != NULL((void*)0)) {
3582 xmlSchemaComponentListFree(bucket->locals);
3583 xmlSchemaItemListFree(bucket->locals);
3584 }
3585 if (bucket->relations != NULL((void*)0)) {
3586 xmlSchemaSchemaRelationPtr prev, cur = bucket->relations;
3587 do {
3588 prev = cur;
3589 cur = cur->next;
3590 xmlFree(prev);
3591 } while (cur != NULL((void*)0));
3592 }
3593 if ((! bucket->preserveDoc) && (bucket->doc != NULL((void*)0))) {
3594 xmlFreeDoc(bucket->doc);
3595 }
3596 if (bucket->type == XML_SCHEMA_SCHEMA_IMPORT1) {
3597 if (WXS_IMPBUCKET(bucket)((xmlSchemaImportPtr) (bucket))->schema != NULL((void*)0))
3598 xmlSchemaFree(WXS_IMPBUCKET(bucket)((xmlSchemaImportPtr) (bucket))->schema);
3599 }
3600 xmlFree(bucket);
3601}
3602
3603static void
3604xmlSchemaBucketFreeEntry(void *bucket, const xmlChar *name ATTRIBUTE_UNUSED__attribute__((unused)))
3605{
3606 xmlSchemaBucketFree((xmlSchemaBucketPtr) bucket);
3607}
3608
3609static xmlSchemaBucketPtr
3610xmlSchemaBucketCreate(xmlSchemaParserCtxtPtr pctxt,
3611 int type, const xmlChar *targetNamespace)
3612{
3613 xmlSchemaBucketPtr ret;
3614 int size;
3615 xmlSchemaPtr mainSchema;
3616
3617 if (WXS_CONSTRUCTOR(pctxt)(pctxt)->constructor->mainSchema == NULL((void*)0)) {
3618 PERROR_INT("xmlSchemaBucketCreate",xmlSchemaInternalErr((xmlSchemaAbstractCtxtPtr) pctxt, "xmlSchemaBucketCreate"
, "no main schema on constructor");
3619 "no main schema on constructor")xmlSchemaInternalErr((xmlSchemaAbstractCtxtPtr) pctxt, "xmlSchemaBucketCreate"
, "no main schema on constructor");
;
3620 return(NULL((void*)0));
3621 }
3622 mainSchema = WXS_CONSTRUCTOR(pctxt)(pctxt)->constructor->mainSchema;
3623 /* Create the schema bucket. */
3624 if (WXS_IS_BUCKET_INCREDEF(type)(((type) == 2) || ((type) == 3)))
3625 size = sizeof(xmlSchemaInclude);
3626 else
3627 size = sizeof(xmlSchemaImport);
3628 ret = (xmlSchemaBucketPtr) xmlMalloc(size);
3629 if (ret == NULL((void*)0)) {
3630 xmlSchemaPErrMemory(NULL((void*)0), "allocating schema bucket", NULL((void*)0));
3631 return(NULL((void*)0));
3632 }
3633 memset(ret, 0, size);
3634 ret->targetNamespace = targetNamespace;
3635 ret->type = type;
3636 ret->globals = xmlSchemaItemListCreate();
3637 if (ret->globals == NULL((void*)0)) {
3638 xmlSchemaBucketFree(ret);
3639 return(NULL((void*)0));
3640 }
3641 ret->locals = xmlSchemaItemListCreate();
3642 if (ret->locals == NULL((void*)0)) {
3643 xmlSchemaBucketFree(ret);
3644 return(NULL((void*)0));
3645 }
3646 /*
3647 * The following will assure that only the first bucket is marked as
3648 * XML_SCHEMA_SCHEMA_MAIN and it points to the *main* schema.
3649 * For each following import buckets an xmlSchema will be created.
3650 * An xmlSchema will be created for every distinct targetNamespace.
3651 * We assign the targetNamespace to the schemata here.
3652 */
3653 if (! WXS_HAS_BUCKETS(pctxt)( (((pctxt))->constructor->buckets != ((void*)0)) &&
(((pctxt))->constructor->buckets->nbItems > 0) )
) {
3654 if (WXS_IS_BUCKET_INCREDEF(type)(((type) == 2) || ((type) == 3))) {
3655 PERROR_INT("xmlSchemaBucketCreate",xmlSchemaInternalErr((xmlSchemaAbstractCtxtPtr) pctxt, "xmlSchemaBucketCreate"
, "first bucket but it's an include or redefine");
3656 "first bucket but it's an include or redefine")xmlSchemaInternalErr((xmlSchemaAbstractCtxtPtr) pctxt, "xmlSchemaBucketCreate"
, "first bucket but it's an include or redefine");
;
3657 xmlSchemaBucketFree(ret);
3658 return(NULL((void*)0));
3659 }
3660 /* Force the type to be XML_SCHEMA_SCHEMA_MAIN. */
3661 ret->type = XML_SCHEMA_SCHEMA_MAIN0;
3662 /* Point to the *main* schema. */
3663 WXS_CONSTRUCTOR(pctxt)(pctxt)->constructor->mainBucket = ret;
3664 WXS_IMPBUCKET(ret)((xmlSchemaImportPtr) (ret))->schema = mainSchema;
3665 /*
3666 * Ensure that the main schema gets a targetNamespace.
3667 */
3668 mainSchema->targetNamespace = targetNamespace;
3669 } else {
3670 if (type == XML_SCHEMA_SCHEMA_MAIN0) {
3671 PERROR_INT("xmlSchemaBucketCreate",xmlSchemaInternalErr((xmlSchemaAbstractCtxtPtr) pctxt, "xmlSchemaBucketCreate"
, "main bucket but it's not the first one");
3672 "main bucket but it's not the first one")xmlSchemaInternalErr((xmlSchemaAbstractCtxtPtr) pctxt, "xmlSchemaBucketCreate"
, "main bucket but it's not the first one");
;
3673 xmlSchemaBucketFree(ret);
3674 return(NULL((void*)0));
3675 } else if (type == XML_SCHEMA_SCHEMA_IMPORT1) {
3676 /*
3677 * Create a schema for imports and assign the
3678 * targetNamespace.
3679 */
3680 WXS_IMPBUCKET(ret)((xmlSchemaImportPtr) (ret))->schema = xmlSchemaNewSchema(pctxt);
3681 if (WXS_IMPBUCKET(ret)((xmlSchemaImportPtr) (ret))->schema == NULL((void*)0)) {
3682 xmlSchemaBucketFree(ret);
3683 return(NULL((void*)0));
3684 }
3685 WXS_IMPBUCKET(ret)((xmlSchemaImportPtr) (ret))->schema->targetNamespace = targetNamespace;
3686 }
3687 }
3688 if (WXS_IS_BUCKET_IMPMAIN(type)(((type) == 0) || ((type) == 1))) {
3689 int res;
3690 /*
3691 * Imports go into the "schemasImports" slot of the main *schema*.
3692 * Note that we create an import entry for the main schema as well; i.e.,
3693 * even if there's only one schema, we'll get an import.
3694 */
3695 if (mainSchema->schemasImports == NULL((void*)0)) {
3696 mainSchema->schemasImports = xmlHashCreateDict(5,
3697 WXS_CONSTRUCTOR(pctxt)(pctxt)->constructor->dict);
3698 if (mainSchema->schemasImports == NULL((void*)0)) {
3699 xmlSchemaBucketFree(ret);
3700 return(NULL((void*)0));
3701 }
3702 }
3703 if (targetNamespace == NULL((void*)0))
3704 res = xmlHashAddEntry(mainSchema->schemasImports,
3705 XML_SCHEMAS_NO_NAMESPACE(const xmlChar *) "##", ret);
3706 else
3707 res = xmlHashAddEntry(mainSchema->schemasImports,
3708 targetNamespace, ret);
3709 if (res != 0) {
3710 PERROR_INT("xmlSchemaBucketCreate",xmlSchemaInternalErr((xmlSchemaAbstractCtxtPtr) pctxt, "xmlSchemaBucketCreate"
, "failed to add the schema bucket to the hash");
3711 "failed to add the schema bucket to the hash")xmlSchemaInternalErr((xmlSchemaAbstractCtxtPtr) pctxt, "xmlSchemaBucketCreate"
, "failed to add the schema bucket to the hash");
;
3712 xmlSchemaBucketFree(ret);
3713 return(NULL((void*)0));
3714 }
3715 } else {
3716 /* Set the @ownerImport of an include bucket. */
3717 if (WXS_IS_BUCKET_IMPMAIN(WXS_CONSTRUCTOR(pctxt)->bucket->type)((((pctxt)->constructor->bucket->type) == 0) || (((pctxt
)->constructor->bucket->type) == 1))
)
3718 WXS_INCBUCKET(ret)((xmlSchemaIncludePtr) (ret))->ownerImport =
3719 WXS_IMPBUCKET(WXS_CONSTRUCTOR(pctxt)->bucket)((xmlSchemaImportPtr) ((pctxt)->constructor->bucket));
3720 else
3721 WXS_INCBUCKET(ret)((xmlSchemaIncludePtr) (ret))->ownerImport =
3722 WXS_INCBUCKET(WXS_CONSTRUCTOR(pctxt)->bucket)((xmlSchemaIncludePtr) ((pctxt)->constructor->bucket))->ownerImport;
3723
3724 /* Includes got into the "includes" slot of the *main* schema. */
3725 if (mainSchema->includes == NULL((void*)0)) {
3726 mainSchema->includes = xmlSchemaItemListCreate();
3727 if (mainSchema->includes == NULL((void*)0)) {
3728 xmlSchemaBucketFree(ret);
3729 return(NULL((void*)0));
3730 }
3731 }
3732 if (xmlSchemaItemListAdd(mainSchema->includes, ret) < 0) {
3733 xmlSchemaBucketFree(ret);
3734 return(NULL((void*)0));
3735 }
3736 }
3737 /*
3738 * Add to list of all buckets; this is used for lookup
3739 * during schema construction time only.
3740 */
3741 if (xmlSchemaItemListAdd(WXS_CONSTRUCTOR(pctxt)(pctxt)->constructor->buckets, ret) == -1)
3742 return(NULL((void*)0));
3743 return(ret);
3744}
3745
3746static int
3747xmlSchemaAddItemSize(xmlSchemaItemListPtr *list, int initialSize, void *item)
3748{
3749 if (*list == NULL((void*)0)) {
3750 *list = xmlSchemaItemListCreate();
3751 if (*list == NULL((void*)0))
3752 return(-1);
3753 }
3754 return(xmlSchemaItemListAddSize(*list, initialSize, item));
3755}
3756
3757/**
3758 * xmlSchemaFreeAnnot:
3759 * @annot: a schema type structure
3760 *
3761 * Deallocate a annotation structure
3762 */
3763static void
3764xmlSchemaFreeAnnot(xmlSchemaAnnotPtr annot)
3765{
3766 if (annot == NULL((void*)0))
3767 return;
3768 if (annot->next == NULL((void*)0)) {
3769 xmlFree(annot);
3770 } else {
3771 xmlSchemaAnnotPtr prev;
3772
3773 do {
3774 prev = annot;
3775 annot = annot->next;
3776 xmlFree(prev);
3777 } while (annot != NULL((void*)0));
3778 }
3779}
3780
3781/**
3782 * xmlSchemaFreeNotation:
3783 * @schema: a schema notation structure
3784 *
3785 * Deallocate a Schema Notation structure.
3786 */
3787static void
3788xmlSchemaFreeNotation(xmlSchemaNotationPtr nota)
3789{
3790 if (nota == NULL((void*)0))
3791 return;
3792 if (nota->annot != NULL((void*)0))
3793 xmlSchemaFreeAnnot(nota->annot);
3794 xmlFree(nota);
3795}
3796
3797/**
3798 * xmlSchemaFreeAttribute:
3799 * @attr: an attribute declaration
3800 *
3801 * Deallocates an attribute declaration structure.
3802 */
3803static void
3804xmlSchemaFreeAttribute(xmlSchemaAttributePtr attr)
3805{
3806 if (attr == NULL((void*)0))
3807 return;
3808 if (attr->annot != NULL((void*)0))
3809 xmlSchemaFreeAnnot(attr->annot);
3810 if (attr->defVal != NULL((void*)0))
3811 xmlSchemaFreeValue(attr->defVal);
3812 xmlFree(attr);
3813}
3814
3815/**
3816 * xmlSchemaFreeAttributeUse:
3817 * @use: an attribute use
3818 *
3819 * Deallocates an attribute use structure.
3820 */
3821static void
3822xmlSchemaFreeAttributeUse(xmlSchemaAttributeUsePtr use)
3823{
3824 if (use == NULL((void*)0))
3825 return;
3826 if (use->annot != NULL((void*)0))
3827 xmlSchemaFreeAnnot(use->annot);
3828 if (use->defVal != NULL((void*)0))
3829 xmlSchemaFreeValue(use->defVal);
3830 xmlFree(use);
3831}
3832
3833/**
3834 * xmlSchemaFreeAttributeUseProhib:
3835 * @prohib: an attribute use prohibition
3836 *
3837 * Deallocates an attribute use structure.
3838 */
3839static void
3840xmlSchemaFreeAttributeUseProhib(xmlSchemaAttributeUseProhibPtr prohib)
3841{
3842 if (prohib == NULL((void*)0))
3843 return;
3844 xmlFree(prohib);
3845}
3846
3847/**
3848 * xmlSchemaFreeWildcardNsSet:
3849 * set: a schema wildcard namespace
3850 *
3851 * Deallocates a list of wildcard constraint structures.
3852 */
3853static void
3854xmlSchemaFreeWildcardNsSet(xmlSchemaWildcardNsPtr set)
3855{
3856 xmlSchemaWildcardNsPtr next;
3857
3858 while (set != NULL((void*)0)) {
3859 next = set->next;
3860 xmlFree(set);
3861 set = next;
3862 }
3863}
3864
3865/**
3866 * xmlSchemaFreeWildcard:
3867 * @wildcard: a wildcard structure
3868 *
3869 * Deallocates a wildcard structure.
3870 */
3871void
3872xmlSchemaFreeWildcard(xmlSchemaWildcardPtr wildcard)
3873{
3874 if (wildcard == NULL((void*)0))
3875 return;
3876 if (wildcard->annot != NULL((void*)0))
3877 xmlSchemaFreeAnnot(wildcard->annot);
3878 if (wildcard->nsSet != NULL((void*)0))
3879 xmlSchemaFreeWildcardNsSet(wildcard->nsSet);
3880 if (wildcard->negNsSet != NULL((void*)0))
3881 xmlFree(wildcard->negNsSet);
3882 xmlFree(wildcard);
3883}
3884
3885/**
3886 * xmlSchemaFreeAttributeGroup:
3887 * @schema: a schema attribute group structure
3888 *
3889 * Deallocate a Schema Attribute Group structure.
3890 */
3891static void
3892xmlSchemaFreeAttributeGroup(xmlSchemaAttributeGroupPtr attrGr)
3893{
3894 if (attrGr == NULL((void*)0))
3895 return;
3896 if (attrGr->annot != NULL((void*)0))
3897 xmlSchemaFreeAnnot(attrGr->annot);
3898 if (attrGr->attrUses != NULL((void*)0))
3899 xmlSchemaItemListFree(WXS_LIST_CAST(xmlSchemaItemListPtr) attrGr->attrUses);
3900 xmlFree(attrGr);
3901}
3902
3903/**
3904 * xmlSchemaFreeQNameRef:
3905 * @item: a QName reference structure
3906 *
3907 * Deallocatea a QName reference structure.
3908 */
3909static void
3910xmlSchemaFreeQNameRef(xmlSchemaQNameRefPtr item)
3911{
3912 xmlFree(item);
3913}
3914
3915/**
3916 * xmlSchemaFreeTypeLinkList:
3917 * @alink: a type link
3918 *
3919 * Deallocate a list of types.
3920 */
3921static void
3922xmlSchemaFreeTypeLinkList(xmlSchemaTypeLinkPtr link)
3923{
3924 xmlSchemaTypeLinkPtr next;
3925
3926 while (link != NULL((void*)0)) {
3927 next = link->next;
3928 xmlFree(link);
3929 link = next;
3930 }
3931}
3932
3933static void
3934xmlSchemaFreeIDCStateObjList(xmlSchemaIDCStateObjPtr sto)
3935{
3936 xmlSchemaIDCStateObjPtr next;
3937 while (sto != NULL((void*)0)) {
3938 next = sto->next;
3939 if (sto->history != NULL((void*)0))
3940 xmlFree(sto->history);
3941 if (sto->xpathCtxt != NULL((void*)0))
3942 xmlFreeStreamCtxt((xmlStreamCtxtPtr) sto->xpathCtxt);
3943 xmlFree(sto);
3944 sto = next;
3945 }
3946}
3947
3948/**
3949 * xmlSchemaFreeIDC:
3950 * @idc: a identity-constraint definition
3951 *
3952 * Deallocates an identity-constraint definition.
3953 */
3954static void
3955xmlSchemaFreeIDC(xmlSchemaIDCPtr idcDef)
3956{
3957 xmlSchemaIDCSelectPtr cur, prev;
3958
3959 if (idcDef == NULL((void*)0))
3960 return;
3961 if (idcDef->annot != NULL((void*)0))
3962 xmlSchemaFreeAnnot(idcDef->annot);
3963 /* Selector */
3964 if (idcDef->selector != NULL((void*)0)) {
3965 if (idcDef->selector->xpathComp != NULL((void*)0))
3966 xmlFreePattern((xmlPatternPtr) idcDef->selector->xpathComp);
3967 xmlFree(idcDef->selector);
3968 }
3969 /* Fields */
3970 if (idcDef->fields != NULL((void*)0)) {
3971 cur = idcDef->fields;
3972 do {
3973 prev = cur;
3974 cur = cur->next;
3975 if (prev->xpathComp != NULL((void*)0))
3976 xmlFreePattern((xmlPatternPtr) prev->xpathComp);
3977 xmlFree(prev);
3978 } while (cur != NULL((void*)0));
3979 }
3980 xmlFree(idcDef);
3981}
3982
3983/**
3984 * xmlSchemaFreeElement:
3985 * @schema: a schema element structure
3986 *
3987 * Deallocate a Schema Element structure.
3988 */
3989static void
3990xmlSchemaFreeElement(xmlSchemaElementPtr elem)
3991{
3992 if (elem == NULL((void*)0))
3993 return;
3994 if (elem->annot != NULL((void*)0))
3995 xmlSchemaFreeAnnot(elem->annot);
3996 if (elem->contModel != NULL((void*)0))
3997 xmlRegFreeRegexp(elem->contModel);
3998 if (elem->defVal != NULL((void*)0))
3999 xmlSchemaFreeValue(elem->defVal);
4000 xmlFree(elem);
4001}
4002
4003/**
4004 * xmlSchemaFreeFacet:
4005 * @facet: a schema facet structure
4006 *
4007 * Deallocate a Schema Facet structure.
4008 */
4009void
4010xmlSchemaFreeFacet(xmlSchemaFacetPtr facet)
4011{
4012 if (facet == NULL((void*)0))
4013 return;
4014 if (facet->val != NULL((void*)0))
4015 xmlSchemaFreeValue(facet->val);
4016 if (facet->regexp != NULL((void*)0))
4017 xmlRegFreeRegexp(facet->regexp);
4018 if (facet->annot != NULL((void*)0))
4019 xmlSchemaFreeAnnot(facet->annot);
4020 xmlFree(facet);
4021}
4022
4023/**
4024 * xmlSchemaFreeType:
4025 * @type: a schema type structure
4026 *
4027 * Deallocate a Schema Type structure.
4028 */
4029void
4030xmlSchemaFreeType(xmlSchemaTypePtr type)
4031{
4032 if (type == NULL((void*)0))
4033 return;
4034 if (type->annot != NULL((void*)0))
4035 xmlSchemaFreeAnnot(type->annot);
4036 if (type->facets != NULL((void*)0)) {
4037 xmlSchemaFacetPtr facet, next;
4038
4039 facet = type->facets;
4040 while (facet != NULL((void*)0)) {
4041 next = facet->next;
4042 xmlSchemaFreeFacet(facet);
4043 facet = next;
4044 }
4045 }
4046 if (type->attrUses != NULL((void*)0))
4047 xmlSchemaItemListFree((xmlSchemaItemListPtr) type->attrUses);
4048 if (type->memberTypes != NULL((void*)0))
4049 xmlSchemaFreeTypeLinkList(type->memberTypes);
4050 if (type->facetSet != NULL((void*)0)) {
4051 xmlSchemaFacetLinkPtr next, link;
4052
4053 link = type->facetSet;
4054 do {
4055 next = link->next;
4056 xmlFree(link);
4057 link = next;
4058 } while (link != NULL((void*)0));
4059 }
4060 if (type->contModel != NULL((void*)0))
4061 xmlRegFreeRegexp(type->contModel);
4062 xmlFree(type);
4063}
4064
4065/**
4066 * xmlSchemaFreeModelGroupDef:
4067 * @item: a schema model group definition
4068 *
4069 * Deallocates a schema model group definition.
4070 */
4071static void
4072xmlSchemaFreeModelGroupDef(xmlSchemaModelGroupDefPtr item)
4073{
4074 if (item->annot != NULL((void*)0))
4075 xmlSchemaFreeAnnot(item->annot);
4076 xmlFree(item);
4077}
4078
4079/**
4080 * xmlSchemaFreeModelGroup:
4081 * @item: a schema model group
4082 *
4083 * Deallocates a schema model group structure.
4084 */
4085static void
4086xmlSchemaFreeModelGroup(xmlSchemaModelGroupPtr item)
4087{
4088 if (item->annot != NULL((void*)0))
4089 xmlSchemaFreeAnnot(item->annot);
4090 xmlFree(item);
4091}
4092
4093static void
4094xmlSchemaComponentListFree(xmlSchemaItemListPtr list)
4095{
4096 if ((list == NULL((void*)0)) || (list->nbItems == 0))
4097 return;
4098 {
4099 xmlSchemaTreeItemPtr item;
4100 xmlSchemaTreeItemPtr *items = (xmlSchemaTreeItemPtr *) list->items;
4101 int i;
4102
4103 for (i = 0; i < list->nbItems; i++) {
4104 item = items[i];
4105 if (item == NULL((void*)0))
4106 continue;
4107 switch (item->type) {
4108 case XML_SCHEMA_TYPE_SIMPLE:
4109 case XML_SCHEMA_TYPE_COMPLEX:
4110 xmlSchemaFreeType((xmlSchemaTypePtr) item);
4111 break;
4112 case XML_SCHEMA_TYPE_ATTRIBUTE:
4113 xmlSchemaFreeAttribute((xmlSchemaAttributePtr) item);
4114 break;
4115 case XML_SCHEMA_TYPE_ATTRIBUTE_USE:
4116 xmlSchemaFreeAttributeUse((xmlSchemaAttributeUsePtr) item);
4117 break;
4118 case XML_SCHEMA_EXTRA_ATTR_USE_PROHIB:
4119 xmlSchemaFreeAttributeUseProhib(
4120 (xmlSchemaAttributeUseProhibPtr) item);
4121 break;
4122 case XML_SCHEMA_TYPE_ELEMENT:
4123 xmlSchemaFreeElement((xmlSchemaElementPtr) item);
4124 break;
4125 case XML_SCHEMA_TYPE_PARTICLE:
4126 if (item->annot != NULL((void*)0))
4127 xmlSchemaFreeAnnot(item->annot);
4128 xmlFree(item);
4129 break;
4130 case XML_SCHEMA_TYPE_SEQUENCE:
4131 case XML_SCHEMA_TYPE_CHOICE:
4132 case XML_SCHEMA_TYPE_ALL:
4133 xmlSchemaFreeModelGroup((xmlSchemaModelGroupPtr) item);
4134 break;
4135 case XML_SCHEMA_TYPE_ATTRIBUTEGROUP:
4136 xmlSchemaFreeAttributeGroup(
4137 (xmlSchemaAttributeGroupPtr) item);
4138 break;
4139 case XML_SCHEMA_TYPE_GROUP:
4140 xmlSchemaFreeModelGroupDef(
4141 (xmlSchemaModelGroupDefPtr) item);
4142 break;
4143 case XML_SCHEMA_TYPE_ANY:
4144 case XML_SCHEMA_TYPE_ANY_ATTRIBUTE:
4145 xmlSchemaFreeWildcard((xmlSchemaWildcardPtr) item);
4146 break;
4147 case XML_SCHEMA_TYPE_IDC_KEY:
4148 case XML_SCHEMA_TYPE_IDC_UNIQUE:
4149 case XML_SCHEMA_TYPE_IDC_KEYREF:
4150 xmlSchemaFreeIDC((xmlSchemaIDCPtr) item);
4151 break;
4152 case XML_SCHEMA_TYPE_NOTATION:
4153 xmlSchemaFreeNotation((xmlSchemaNotationPtr) item);
4154 break;
4155 case XML_SCHEMA_EXTRA_QNAMEREF:
4156 xmlSchemaFreeQNameRef((xmlSchemaQNameRefPtr) item);
4157 break;
4158 default: {
4159 /* TODO: This should never be hit. */
4160 xmlSchemaPSimpleInternalErr(NULL((void*)0),
4161 "Internal error: xmlSchemaComponentListFree, "
4162 "unexpected component type '%s'\n",
4163 (const xmlChar *) WXS_ITEM_TYPE_NAME(item)xmlSchemaGetComponentTypeStr((xmlSchemaBasicItemPtr) (item)));
4164 }
4165 break;
4166 }
4167 }
4168 list->nbItems = 0;
4169 }
4170}
4171
4172/**
4173 * xmlSchemaFree:
4174 * @schema: a schema structure
4175 *
4176 * Deallocate a Schema structure.
4177 */
4178void
4179xmlSchemaFree(xmlSchemaPtr schema)
4180{
4181 if (schema == NULL((void*)0))
4182 return;
4183 /* @volatiles is not used anymore :-/ */
4184 if (schema->volatiles != NULL((void*)0))
4185 TODO(*__xmlGenericError())((*__xmlGenericErrorContext()), "Unimplemented block at %s:%d\n"
, "xmlschemas.c", 4185);
4186 /*
4187 * Note that those slots are not responsible for freeing
4188 * schema components anymore; this will now be done by
4189 * the schema buckets.
4190 */
4191 if (schema->notaDecl != NULL((void*)0))
4192 xmlHashFree(schema->notaDecl, NULL((void*)0));
4193 if (schema->attrDecl != NULL((void*)0))
4194 xmlHashFree(schema->attrDecl, NULL((void*)0));
4195 if (schema->attrgrpDecl != NULL((void*)0))
4196 xmlHashFree(schema->attrgrpDecl, NULL((void*)0));
4197 if (schema->elemDecl != NULL((void*)0))
4198 xmlHashFree(schema->elemDecl, NULL((void*)0));
4199 if (schema->typeDecl != NULL((void*)0))
4200 xmlHashFree(schema->typeDecl, NULL((void*)0));
4201 if (schema->groupDecl != NULL((void*)0))
4202 xmlHashFree(schema->groupDecl, NULL((void*)0));
4203 if (schema->idcDef != NULL((void*)0))
4204 xmlHashFree(schema->idcDef, NULL((void*)0));
4205
4206 if (schema->schemasImports != NULL((void*)0))
4207 xmlHashFree(schema->schemasImports, xmlSchemaBucketFreeEntry);
4208 if (schema->includes != NULL((void*)0)) {
4209 xmlSchemaItemListPtr list = (xmlSchemaItemListPtr) schema->includes;
4210 int i;
4211 for (i = 0; i < list->nbItems; i++) {
4212 xmlSchemaBucketFree((xmlSchemaBucketPtr) list->items[i]);
4213 }
4214 xmlSchemaItemListFree(list);
4215 }
4216 if (schema->annot != NULL((void*)0))
4217 xmlSchemaFreeAnnot(schema->annot);
4218 /* Never free the doc here, since this will be done by the buckets. */
4219
4220 xmlDictFree(schema->dict);
4221 xmlFree(schema);
4222}
4223
4224/************************************************************************
4225 * *
4226 * Debug functions *
4227 * *
4228 ************************************************************************/
4229
4230#ifdef LIBXML_OUTPUT_ENABLED
4231
4232static void
4233xmlSchemaTypeDump(xmlSchemaTypePtr type, FILE * output); /* forward */
4234
4235/**
4236 * xmlSchemaElementDump:
4237 * @elem: an element
4238 * @output: the file output
4239 *
4240 * Dump the element
4241 */
4242static void
4243xmlSchemaElementDump(void *payload, void *data,
4244 const xmlChar * name ATTRIBUTE_UNUSED__attribute__((unused)),
4245 const xmlChar * namespace ATTRIBUTE_UNUSED__attribute__((unused)),
4246 const xmlChar * context ATTRIBUTE_UNUSED__attribute__((unused)))
4247{
4248 xmlSchemaElementPtr elem = (xmlSchemaElementPtr) payload;
4249 FILE *output = (FILE *) data;
4250 if (elem == NULL((void*)0))
4251 return;
4252
4253
4254 fprintf(output, "Element");
4255 if (elem->flags & XML_SCHEMAS_ELEM_GLOBAL1 << 1)
4256 fprintf(output, " (global)");
4257 fprintf(output, ": '%s' ", elem->name);
4258 if (namespace != NULL((void*)0))
4259 fprintf(output, "ns '%s'", namespace);
4260 fprintf(output, "\n");
4261#if 0
4262 if ((elem->minOccurs != 1) || (elem->maxOccurs != 1)) {
4263 fprintf(output, " min %d ", elem->minOccurs);
4264 if (elem->maxOccurs >= UNBOUNDED(1 << 30))
4265 fprintf(output, "max: unbounded\n");
4266 else if (elem->maxOccurs != 1)
4267 fprintf(output, "max: %d\n", elem->maxOccurs);
4268 else
4269 fprintf(output, "\n");
4270 }
4271#endif
4272 /*
4273 * Misc other properties.
4274 */
4275 if ((elem->flags & XML_SCHEMAS_ELEM_NILLABLE1 << 0) ||
4276 (elem->flags & XML_SCHEMAS_ELEM_ABSTRACT1 << 4) ||
4277 (elem->flags & XML_SCHEMAS_ELEM_FIXED1 << 3) ||
4278 (elem->flags & XML_SCHEMAS_ELEM_DEFAULT1 << 2)) {
4279 fprintf(output, " props: ");
4280 if (elem->flags & XML_SCHEMAS_ELEM_FIXED1 << 3)
4281 fprintf(output, "[fixed] ");
4282 if (elem->flags & XML_SCHEMAS_ELEM_DEFAULT1 << 2)
4283 fprintf(output, "[default] ");
4284 if (elem->flags & XML_SCHEMAS_ELEM_ABSTRACT1 << 4)
4285 fprintf(output, "[abstract] ");
4286 if (elem->flags & XML_SCHEMAS_ELEM_NILLABLE1 << 0)
4287 fprintf(output, "[nillable] ");
4288 fprintf(output, "\n");
4289 }
4290 /*
4291 * Default/fixed value.
4292 */
4293 if (elem->value != NULL((void*)0))
4294 fprintf(output, " value: '%s'\n", elem->value);
4295 /*
4296 * Type.
4297 */
4298 if (elem->namedType != NULL((void*)0)) {
4299 fprintf(output, " type: '%s' ", elem->namedType);
4300 if (elem->namedTypeNs != NULL((void*)0))
4301 fprintf(output, "ns '%s'\n", elem->namedTypeNs);
4302 else
4303 fprintf(output, "\n");
4304 } else if (elem->subtypes != NULL((void*)0)) {
4305 /*
4306 * Dump local types.
4307 */
4308 xmlSchemaTypeDump(elem->subtypes, output);
4309 }
4310 /*
4311 * Substitution group.
4312 */
4313 if (elem->substGroup != NULL((void*)0)) {
4314 fprintf(output, " substitutionGroup: '%s' ", elem->substGroup);
4315 if (elem->substGroupNs != NULL((void*)0))
4316 fprintf(output, "ns '%s'\n", elem->substGroupNs);
4317 else
4318 fprintf(output, "\n");
4319 }
4320}
4321
4322/**
4323 * xmlSchemaAnnotDump:
4324 * @output: the file output
4325 * @annot: a annotation
4326 *
4327 * Dump the annotation
4328 */
4329static void
4330xmlSchemaAnnotDump(FILE * output, xmlSchemaAnnotPtr annot)
4331{
4332 xmlChar *content;
4333
4334 if (annot == NULL((void*)0))
4335 return;
4336
4337 content = xmlNodeGetContent(annot->content);
4338 if (content != NULL((void*)0)) {
4339 fprintf(output, " Annot: %s\n", content);
4340 xmlFree(content);
4341 } else
4342 fprintf(output, " Annot: empty\n");
4343}
4344
4345/**
4346 * xmlSchemaContentModelDump:
4347 * @particle: the schema particle
4348 * @output: the file output
4349 * @depth: the depth used for indentation
4350 *
4351 * Dump a SchemaType structure
4352 */
4353static void
4354xmlSchemaContentModelDump(xmlSchemaParticlePtr particle, FILE * output, int depth)
4355{
4356 xmlChar *str = NULL((void*)0);
4357 xmlSchemaTreeItemPtr term;
4358 char shift[100];
4359 int i;
4360
4361 if (particle == NULL((void*)0))
4362 return;
4363 for (i = 0;((i < depth) && (i < 25));i++)
4364 shift[2 * i] = shift[2 * i + 1] = ' ';
4365 shift[2 * i] = shift[2 * i + 1] = 0;
4366 fprintf(output, "%s", shift);
4367 if (particle->children == NULL((void*)0)) {
4368 fprintf(output, "MISSING particle term\n");
4369 return;
4370 }
4371 term = particle->children;
4372 if (term == NULL((void*)0)) {
4373 fprintf(output, "(NULL)");
4374 } else {
4375 switch (term->type) {
4376 case XML_SCHEMA_TYPE_ELEMENT:
4377 fprintf(output, "ELEM '%s'", xmlSchemaFormatQName(&str,
4378 ((xmlSchemaElementPtr)term)->targetNamespace,
4379 ((xmlSchemaElementPtr)term)->name));
4380 FREE_AND_NULL(str)if ((str) != ((void*)0)) { xmlFree((xmlChar *) (str)); str = (
(void*)0); }
;
4381 break;
4382 case XML_SCHEMA_TYPE_SEQUENCE:
4383 fprintf(output, "SEQUENCE");
4384 break;
4385 case XML_SCHEMA_TYPE_CHOICE:
4386 fprintf(output, "CHOICE");
4387 break;
4388 case XML_SCHEMA_TYPE_ALL:
4389 fprintf(output, "ALL");
4390 break;
4391 case XML_SCHEMA_TYPE_ANY:
4392 fprintf(output, "ANY");
4393 break;
4394 default:
4395 fprintf(output, "UNKNOWN\n");
4396 return;
4397 }
4398 }
4399 if (particle->minOccurs != 1)
4400 fprintf(output, " min: %d", particle->minOccurs);
4401 if (particle->maxOccurs >= UNBOUNDED(1 << 30))
4402 fprintf(output, " max: unbounded");
4403 else if (particle->maxOccurs != 1)
4404 fprintf(output, " max: %d", particle->maxOccurs);
4405 fprintf(output, "\n");
4406 if (term &&
4407 ((term->type == XML_SCHEMA_TYPE_SEQUENCE) ||
4408 (term->type == XML_SCHEMA_TYPE_CHOICE) ||
4409 (term->type == XML_SCHEMA_TYPE_ALL)) &&
4410 (term->children != NULL((void*)0))) {
4411 xmlSchemaContentModelDump((xmlSchemaParticlePtr) term->children,
4412 output, depth +1);
4413 }
4414 if (particle->next != NULL((void*)0))
4415 xmlSchemaContentModelDump((xmlSchemaParticlePtr) particle->next,
4416 output, depth);
4417}
4418
4419/**
4420 * xmlSchemaAttrUsesDump:
4421 * @uses: attribute uses list
4422 * @output: the file output
4423 *
4424 * Dumps a list of attribute use components.
4425 */
4426static void
4427xmlSchemaAttrUsesDump(xmlSchemaItemListPtr uses, FILE * output)
4428{
4429 xmlSchemaAttributeUsePtr use;
4430 xmlSchemaAttributeUseProhibPtr prohib;
4431 xmlSchemaQNameRefPtr ref;
4432 const xmlChar *name, *tns;
4433 xmlChar *str = NULL((void*)0);
4434 int i;
4435
4436 if ((uses == NULL((void*)0)) || (uses->nbItems == 0))
4437 return;
4438
4439 fprintf(output, " attributes:\n");
4440 for (i = 0; i < uses->nbItems; i++) {
4441 use = uses->items[i];
4442 if (use->type == XML_SCHEMA_EXTRA_ATTR_USE_PROHIB) {
4443 fprintf(output, " [prohibition] ");
4444 prohib = (xmlSchemaAttributeUseProhibPtr) use;
4445 name = prohib->name;
4446 tns = prohib->targetNamespace;
4447 } else if (use->type == XML_SCHEMA_EXTRA_QNAMEREF) {
4448 fprintf(output, " [reference] ");
4449 ref = (xmlSchemaQNameRefPtr) use;
4450 name = ref->name;
4451 tns = ref->targetNamespace;
4452 } else {
4453 fprintf(output, " [use] ");
4454 name = WXS_ATTRUSE_DECL_NAME(use)(((xmlSchemaAttributeUsePtr) (use))->attrDecl)->name;
4455 tns = WXS_ATTRUSE_DECL_TNS(use)(((xmlSchemaAttributeUsePtr) (use))->attrDecl)->targetNamespace;
4456 }
4457 fprintf(output, "'%s'\n",
4458 (const char *) xmlSchemaFormatQName(&str, tns, name));
4459 FREE_AND_NULL(str)if ((str) != ((void*)0)) { xmlFree((xmlChar *) (str)); str = (
(void*)0); }
;
4460 }
4461}
4462
4463/**
4464 * xmlSchemaTypeDump:
4465 * @output: the file output
4466 * @type: a type structure
4467 *
4468 * Dump a SchemaType structure
4469 */
4470static void
4471xmlSchemaTypeDump(xmlSchemaTypePtr type, FILE * output)
4472{
4473 if (type == NULL((void*)0)) {
4474 fprintf(output, "Type: NULL\n");
4475 return;
4476 }
4477 fprintf(output, "Type: ");
4478 if (type->name != NULL((void*)0))
4479 fprintf(output, "'%s' ", type->name);
4480 else
4481 fprintf(output, "(no name) ");
4482 if (type->targetNamespace != NULL((void*)0))
4483 fprintf(output, "ns '%s' ", type->targetNamespace);
4484 switch (type->type) {
4485 case XML_SCHEMA_TYPE_BASIC:
4486 fprintf(output, "[basic] ");
4487 break;
4488 case XML_SCHEMA_TYPE_SIMPLE:
4489 fprintf(output, "[simple] ");
4490 break;
4491 case XML_SCHEMA_TYPE_COMPLEX:
4492 fprintf(output, "[complex] ");
4493 break;
4494 case XML_SCHEMA_TYPE_SEQUENCE:
4495 fprintf(output, "[sequence] ");
4496 break;
4497 case XML_SCHEMA_TYPE_CHOICE:
4498 fprintf(output, "[choice] ");
4499 break;
4500 case XML_SCHEMA_TYPE_ALL:
4501 fprintf(output, "[all] ");
4502 break;
4503 case XML_SCHEMA_TYPE_UR:
4504 fprintf(output, "[ur] ");
4505 break;
4506 case XML_SCHEMA_TYPE_RESTRICTION:
4507 fprintf(output, "[restriction] ");
4508 break;
4509 case XML_SCHEMA_TYPE_EXTENSION:
4510 fprintf(output, "[extension] ");
4511 break;
4512 default:
4513 fprintf(output, "[unknown type %d] ", type->type);
4514 break;
4515 }
4516 fprintf(output, "content: ");
4517 switch (type->contentType) {
4518 case XML_SCHEMA_CONTENT_UNKNOWN:
4519 fprintf(output, "[unknown] ");
4520 break;
4521 case XML_SCHEMA_CONTENT_EMPTY:
4522 fprintf(output, "[empty] ");
4523 break;
4524 case XML_SCHEMA_CONTENT_ELEMENTS:
4525 fprintf(output, "[element] ");
4526 break;
4527 case XML_SCHEMA_CONTENT_MIXED:
4528 fprintf(output, "[mixed] ");
4529 break;
4530 case XML_SCHEMA_CONTENT_MIXED_OR_ELEMENTS:
4531 /* not used. */
4532 break;
4533 case XML_SCHEMA_CONTENT_BASIC:
4534 fprintf(output, "[basic] ");
4535 break;
4536 case XML_SCHEMA_CONTENT_SIMPLE:
4537 fprintf(output, "[simple] ");
4538 break;
4539 case XML_SCHEMA_CONTENT_ANY:
4540 fprintf(output, "[any] ");
4541 break;
4542 }
4543 fprintf(output, "\n");
4544 if (type->base != NULL((void*)0)) {
4545 fprintf(output, " base type: '%s'", type->base);
4546 if (type->baseNs != NULL((void*)0))
4547 fprintf(output, " ns '%s'\n", type->baseNs);
4548 else
4549 fprintf(output, "\n");
4550 }
4551 if (type->attrUses != NULL((void*)0))
4552 xmlSchemaAttrUsesDump(type->attrUses, output);
4553 if (type->annot != NULL((void*)0))
4554 xmlSchemaAnnotDump(output, type->annot);
4555#ifdef DUMP_CONTENT_MODEL
4556 if ((type->type == XML_SCHEMA_TYPE_COMPLEX) &&
4557 (type->subtypes != NULL((void*)0))) {
4558 xmlSchemaContentModelDump((xmlSchemaParticlePtr) type->subtypes,
4559 output, 1);
4560 }
4561#endif
4562}
4563
4564static void
4565xmlSchemaTypeDumpEntry(void *type, void *output,
4566 const xmlChar *name ATTRIBUTE_UNUSED__attribute__((unused)))
4567{
4568 xmlSchemaTypeDump((xmlSchemaTypePtr) type, (FILE *) output);
4569}
4570
4571/**
4572 * xmlSchemaDump:
4573 * @output: the file output
4574 * @schema: a schema structure
4575 *
4576 * Dump a Schema structure.
4577 */
4578void
4579xmlSchemaDump(FILE * output, xmlSchemaPtr schema)
4580{
4581 if (output == NULL((void*)0))
4582 return;
4583 if (schema == NULL((void*)0)) {
4584 fprintf(output, "Schemas: NULL\n");
4585 return;
4586 }
4587 fprintf(output, "Schemas: ");
4588 if (schema->name != NULL((void*)0))
4589 fprintf(output, "%s, ", schema->name);
4590 else
4591 fprintf(output, "no name, ");
4592 if (schema->targetNamespace != NULL((void*)0))
4593 fprintf(output, "%s", (const char *) schema->targetNamespace);
4594 else
4595 fprintf(output, "no target namespace");
4596 fprintf(output, "\n");
4597 if (schema->annot != NULL((void*)0))
4598 xmlSchemaAnnotDump(output, schema->annot);
4599 xmlHashScan(schema->typeDecl, xmlSchemaTypeDumpEntry, output);
4600 xmlHashScanFull(schema->elemDecl, xmlSchemaElementDump, output);
4601}
4602
4603#endif /* LIBXML_OUTPUT_ENABLED */
4604
4605/************************************************************************
4606 * *
4607 * Utilities *
4608 * *
4609 ************************************************************************/
4610
4611/**
4612 * xmlSchemaGetPropNode:
4613 * @node: the element node
4614 * @name: the name of the attribute
4615 *
4616 * Seeks an attribute with a name of @name in
4617 * no namespace.
4618 *
4619 * Returns the attribute or NULL if not present.
4620 */
4621static xmlAttrPtr
4622xmlSchemaGetPropNode(xmlNodePtr node, const char *name)
4623{
4624 xmlAttrPtr prop;
4625
4626 if ((node == NULL((void*)0)) || (name == NULL((void*)0)))
4627 return(NULL((void*)0));
4628 prop = node->properties;
4629 while (prop != NULL((void*)0)) {
4630 if ((prop->ns == NULL((void*)0)) && xmlStrEqual(prop->name, BAD_CAST(xmlChar *) name))
4631 return(prop);
4632 prop = prop->next;
4633 }
4634 return (NULL((void*)0));
4635}
4636
4637/**
4638 * xmlSchemaGetPropNodeNs:
4639 * @node: the element node
4640 * @uri: the uri
4641 * @name: the name of the attribute
4642 *
4643 * Seeks an attribute with a local name of @name and
4644 * a namespace URI of @uri.
4645 *
4646 * Returns the attribute or NULL if not present.
4647 */
4648static xmlAttrPtr
4649xmlSchemaGetPropNodeNs(xmlNodePtr node, const char *uri, const char *name)
4650{
4651 xmlAttrPtr prop;
4652
4653 if ((node == NULL((void*)0)) || (name == NULL((void*)0)))
4654 return(NULL((void*)0));
4655 prop = node->properties;
4656 while (prop != NULL((void*)0)) {
4657 if ((prop->ns != NULL((void*)0)) &&
4658 xmlStrEqual(prop->name, BAD_CAST(xmlChar *) name) &&
4659 xmlStrEqual(prop->ns->href, BAD_CAST(xmlChar *) uri))
4660 return(prop);
4661 prop = prop->next;
4662 }
4663 return (NULL((void*)0));
4664}
4665
4666static const xmlChar *
4667xmlSchemaGetNodeContent(xmlSchemaParserCtxtPtr ctxt, xmlNodePtr node)
4668{
4669 xmlChar *val;
4670 const xmlChar *ret;
4671
4672 val = xmlNodeGetContent(node);
4673 if (val == NULL((void*)0))
4674 val = xmlStrdup((xmlChar *)"");
4675 ret = xmlDictLookup(ctxt->dict, val, -1);
4676 xmlFree(val);
4677 if (ret == NULL((void*)0))
4678 xmlSchemaPErrMemory(ctxt, "getting node content", node);
4679 return(ret);
4680}
4681
4682static const xmlChar *
4683xmlSchemaGetNodeContentNoDict(xmlNodePtr node)
4684{
4685 return((const xmlChar*) xmlNodeGetContent(node));
4686}
4687
4688/**
4689 * xmlSchemaGetProp:
4690 * @ctxt: the parser context
4691 * @node: the node
4692 * @name: the property name
4693 *
4694 * Read a attribute value and internalize the string
4695 *
4696 * Returns the string or NULL if not present.
4697 */
4698static const xmlChar *
4699xmlSchemaGetProp(xmlSchemaParserCtxtPtr ctxt, xmlNodePtr node,
4700 const char *name)
4701{
4702 xmlChar *val;
4703 const xmlChar *ret;
4704
4705 val = xmlGetNoNsProp(node, BAD_CAST(xmlChar *) name);
4706 if (val == NULL((void*)0))
4707 return(NULL((void*)0));
4708 ret = xmlDictLookup(ctxt->dict, val, -1);
4709 xmlFree(val);
4710 return(ret);
4711}
4712
4713/************************************************************************
4714 * *
4715 * Parsing functions *
4716 * *
4717 ************************************************************************/
4718
4719#define WXS_FIND_GLOBAL_ITEM(slot)if (xmlStrEqual(nsName, schema->targetNamespace)) { ret = xmlHashLookup
(schema->slot, name); if (ret != ((void*)0)) goto exit; } if
(xmlHashSize(schema->schemasImports) > 1) { xmlSchemaImportPtr
import; if (nsName == ((void*)0)) import = xmlHashLookup(schema
->schemasImports, (const xmlChar *) "##"); else import = xmlHashLookup
(schema->schemasImports, nsName); if (import == ((void*)0)
) goto exit; ret = xmlHashLookup(import->schema->slot, name
); }
\
4720 if (xmlStrEqual(nsName, schema->targetNamespace)) { \
4721 ret = xmlHashLookup(schema->slot, name); \
4722 if (ret != NULL((void*)0)) goto exit; \
4723 } \
4724 if (xmlHashSize(schema->schemasImports) > 1) { \
4725 xmlSchemaImportPtr import; \
4726 if (nsName == NULL((void*)0)) \
4727 import = xmlHashLookup(schema->schemasImports, \
4728 XML_SCHEMAS_NO_NAMESPACE(const xmlChar *) "##"); \
4729 else \
4730 import = xmlHashLookup(schema->schemasImports, nsName); \
4731 if (import == NULL((void*)0)) \
4732 goto exit; \
4733 ret = xmlHashLookup(import->schema->slot, name); \
4734 }
4735
4736/**
4737 * xmlSchemaGetElem:
4738 * @schema: the schema context
4739 * @name: the element name
4740 * @ns: the element namespace
4741 *
4742 * Lookup a global element declaration in the schema.
4743 *
4744 * Returns the element declaration or NULL if not found.
4745 */
4746static xmlSchemaElementPtr
4747xmlSchemaGetElem(xmlSchemaPtr schema, const xmlChar * name,
4748 const xmlChar * nsName)
4749{
4750 xmlSchemaElementPtr ret = NULL((void*)0);
4751
4752 if ((name == NULL((void*)0)) || (schema == NULL((void*)0)))
4753 return(NULL((void*)0));
4754 if (schema != NULL((void*)0)) {
4755 WXS_FIND_GLOBAL_ITEM(elemDecl)if (xmlStrEqual(nsName, schema->targetNamespace)) { ret = xmlHashLookup
(schema->elemDecl, name); if (ret != ((void*)0)) goto exit
; } if (xmlHashSize(schema->schemasImports) > 1) { xmlSchemaImportPtr
import; if (nsName == ((void*)0)) import = xmlHashLookup(schema
->schemasImports, (const xmlChar *) "##"); else import = xmlHashLookup
(schema->schemasImports, nsName); if (import == ((void*)0)
) goto exit; ret = xmlHashLookup(import->schema->elemDecl
, name); }
4756 }
4757exit:
4758 return (ret);
4759}
4760
4761/**
4762 * xmlSchemaGetType:
4763 * @schema: the main schema
4764 * @name: the type's name
4765 * nsName: the type's namespace
4766 *
4767 * Lookup a type in the schemas or the predefined types
4768 *
4769 * Returns the group definition or NULL if not found.
4770 */
4771static xmlSchemaTypePtr
4772xmlSchemaGetType(xmlSchemaPtr schema, const xmlChar * name,
4773 const xmlChar * nsName)
4774{
4775 xmlSchemaTypePtr ret = NULL((void*)0);
4776
4777 if (name == NULL((void*)0))
4778 return (NULL((void*)0));
4779 /* First try the built-in types. */
4780 if ((nsName != NULL((void*)0)) && xmlStrEqual(nsName, xmlSchemaNs)) {
4781 ret = xmlSchemaGetPredefinedType(name, nsName);
4782 if (ret != NULL((void*)0))
4783 goto exit;
4784 /*
4785 * Note that we try the parsed schemas as well here
4786 * since one might have parsed the S4S, which contain more
4787 * than the built-in types.
4788 * TODO: Can we optimize this?
4789 */
4790 }
4791 if (schema != NULL((void*)0)) {
4792 WXS_FIND_GLOBAL_ITEM(typeDecl)if (xmlStrEqual(nsName, schema->targetNamespace)) { ret = xmlHashLookup
(schema->typeDecl, name); if (ret != ((void*)0)) goto exit
; } if (xmlHashSize(schema->schemasImports) > 1) { xmlSchemaImportPtr
import; if (nsName == ((void*)0)) import = xmlHashLookup(schema
->schemasImports, (const xmlChar *) "##"); else import = xmlHashLookup
(schema->schemasImports, nsName); if (import == ((void*)0)
) goto exit; ret = xmlHashLookup(import->schema->typeDecl
, name); }
4793 }
4794exit:
4795
4796 return (ret);
4797}
4798
4799/**
4800 * xmlSchemaGetAttributeDecl:
4801 * @schema: the context of the schema
4802 * @name: the name of the attribute
4803 * @ns: the target namespace of the attribute
4804 *
4805 * Lookup a an attribute in the schema or imported schemas
4806 *
4807 * Returns the attribute declaration or NULL if not found.
4808 */
4809static xmlSchemaAttributePtr
4810xmlSchemaGetAttributeDecl(xmlSchemaPtr schema, const xmlChar * name,
4811 const xmlChar * nsName)
4812{
4813 xmlSchemaAttributePtr ret = NULL((void*)0);
4814
4815 if ((name == NULL((void*)0)) || (schema == NULL((void*)0)))
4816 return (NULL((void*)0));
4817 if (schema != NULL((void*)0)) {
4818 WXS_FIND_GLOBAL_ITEM(attrDecl)if (xmlStrEqual(nsName, schema->targetNamespace)) { ret = xmlHashLookup
(schema->attrDecl, name); if (ret != ((void*)0)) goto exit
; } if (xmlHashSize(schema->schemasImports) > 1) { xmlSchemaImportPtr
import; if (nsName == ((void*)0)) import = xmlHashLookup(schema
->schemasImports, (const xmlChar *) "##"); else import = xmlHashLookup
(schema->schemasImports, nsName); if (import == ((void*)0)
) goto exit; ret = xmlHashLookup(import->schema->attrDecl
, name); }
4819 }
4820exit:
4821 return (ret);
4822}
4823
4824/**
4825 * xmlSchemaGetAttributeGroup:
4826 * @schema: the context of the schema
4827 * @name: the name of the attribute group
4828 * @ns: the target namespace of the attribute group
4829 *
4830 * Lookup a an attribute group in the schema or imported schemas
4831 *
4832 * Returns the attribute group definition or NULL if not found.
4833 */
4834static xmlSchemaAttributeGroupPtr
4835xmlSchemaGetAttributeGroup(xmlSchemaPtr schema, const xmlChar * name,
4836 const xmlChar * nsName)
4837{
4838 xmlSchemaAttributeGroupPtr ret = NULL((void*)0);
4839
4840 if ((name == NULL((void*)0)) || (schema == NULL((void*)0)))
4841 return (NULL((void*)0));
4842 if (schema != NULL((void*)0)) {
4843 WXS_FIND_GLOBAL_ITEM(attrgrpDecl)if (xmlStrEqual(nsName, schema->targetNamespace)) { ret = xmlHashLookup
(schema->attrgrpDecl, name); if (ret != ((void*)0)) goto exit
; } if (xmlHashSize(schema->schemasImports) > 1) { xmlSchemaImportPtr
import; if (nsName == ((void*)0)) import = xmlHashLookup(schema
->schemasImports, (const xmlChar *) "##"); else import = xmlHashLookup
(schema->schemasImports, nsName); if (import == ((void*)0)
) goto exit; ret = xmlHashLookup(import->schema->attrgrpDecl
, name); }
4844 }
4845exit:
4846 /* TODO:
4847 if ((ret != NULL) && (ret->redef != NULL)) {
4848 * Return the last redefinition. *
4849 ret = ret->redef;
4850 }
4851 */
4852 return (ret);
4853}
4854
4855/**
4856 * xmlSchemaGetGroup:
4857 * @schema: the context of the schema
4858 * @name: the name of the group
4859 * @ns: the target namespace of the group
4860 *
4861 * Lookup a group in the schema or imported schemas
4862 *
4863 * Returns the group definition or NULL if not found.
4864 */
4865static xmlSchemaModelGroupDefPtr
4866xmlSchemaGetGroup(xmlSchemaPtr schema, const xmlChar * name,
4867 const xmlChar * nsName)
4868{
4869 xmlSchemaModelGroupDefPtr ret = NULL((void*)0);
4870
4871 if ((name == NULL((void*)0)) || (schema == NULL((void*)0)))
4872 return (NULL((void*)0));
4873 if (schema != NULL((void*)0)) {
4874 WXS_FIND_GLOBAL_ITEM(groupDecl)if (xmlStrEqual(nsName, schema->targetNamespace)) { ret = xmlHashLookup
(schema->groupDecl, name); if (ret != ((void*)0)) goto exit
; } if (xmlHashSize(schema->schemasImports) > 1) { xmlSchemaImportPtr
import; if (nsName == ((void*)0)) import = xmlHashLookup(schema
->schemasImports, (const xmlChar *) "##"); else import = xmlHashLookup
(schema->schemasImports, nsName); if (import == ((void*)0)
) goto exit; ret = xmlHashLookup(import->schema->groupDecl
, name); }
4875 }
4876exit:
4877
4878 return (ret);
4879}
4880
4881static xmlSchemaNotationPtr
4882xmlSchemaGetNotation(xmlSchemaPtr schema,
4883 const xmlChar *name,
4884 const xmlChar *nsName)
4885{
4886 xmlSchemaNotationPtr ret = NULL((void*)0);
4887
4888 if ((name == NULL((void*)0)) || (schema == NULL((void*)0)))
4889 return (NULL((void*)0));
4890 if (schema != NULL((void*)0)) {
4891 WXS_FIND_GLOBAL_ITEM(notaDecl)if (xmlStrEqual(nsName, schema->targetNamespace)) { ret = xmlHashLookup
(schema->notaDecl, name); if (ret != ((void*)0)) goto exit
; } if (xmlHashSize(schema->schemasImports) > 1) { xmlSchemaImportPtr
import; if (nsName == ((void*)0)) import = xmlHashLookup(schema
->schemasImports, (const xmlChar *) "##"); else import = xmlHashLookup
(schema->schemasImports, nsName); if (import == ((void*)0)
) goto exit; ret = xmlHashLookup(import->schema->notaDecl
, name); }
4892 }
4893exit:
4894 return (ret);
4895}
4896
4897static xmlSchemaIDCPtr
4898xmlSchemaGetIDC(xmlSchemaPtr schema,
4899 const xmlChar *name,
4900 const xmlChar *nsName)
4901{
4902 xmlSchemaIDCPtr ret = NULL((void*)0);
4903
4904 if ((name == NULL((void*)0)) || (schema == NULL((void*)0)))
4905 return (NULL((void*)0));
4906 if (schema != NULL((void*)0)) {
4907 WXS_FIND_GLOBAL_ITEM(idcDef)if (xmlStrEqual(nsName, schema->targetNamespace)) { ret = xmlHashLookup
(schema->idcDef, name); if (ret != ((void*)0)) goto exit; }
if (xmlHashSize(schema->schemasImports) > 1) { xmlSchemaImportPtr
import; if (nsName == ((void*)0)) import = xmlHashLookup(schema
->schemasImports, (const xmlChar *) "##"); else import = xmlHashLookup
(schema->schemasImports, nsName); if (import == ((void*)0)
) goto exit; ret = xmlHashLookup(import->schema->idcDef
, name); }
4908 }
4909exit:
4910 return (ret);
4911}
4912
4913/**
4914 * xmlSchemaGetNamedComponent:
4915 * @schema: the schema
4916 * @name: the name of the group
4917 * @ns: the target namespace of the group
4918 *
4919 * Lookup a group in the schema or imported schemas
4920 *
4921 * Returns the group definition or NULL if not found.
4922 */
4923static xmlSchemaBasicItemPtr
4924xmlSchemaGetNamedComponent(xmlSchemaPtr schema,
4925 xmlSchemaTypeType itemType,
4926 const xmlChar *name,
4927 const xmlChar *targetNs)
4928{
4929 switch (itemType) {
4930 case XML_SCHEMA_TYPE_GROUP:
4931 return ((xmlSchemaBasicItemPtr) xmlSchemaGetGroup(schema,
4932 name, targetNs));
4933 case XML_SCHEMA_TYPE_ELEMENT:
4934 return ((xmlSchemaBasicItemPtr) xmlSchemaGetElem(schema,
4935 name, targetNs));
4936 default:
4937 TODO(*__xmlGenericError())((*__xmlGenericErrorContext()), "Unimplemented block at %s:%d\n"
, "xmlschemas.c", 4937);
4938 return (NULL((void*)0));
4939 }
4940}
4941
4942/************************************************************************
4943 * *
4944 * Parsing functions *
4945 * *
4946 ************************************************************************/
4947
4948#define IS_BLANK_NODE(n)(((n)->type == XML_TEXT_NODE) && (xmlSchemaIsBlank
((n)->content, -1)))
\
4949 (((n)->type == XML_TEXT_NODE) && (xmlSchemaIsBlank((n)->content, -1)))
4950
4951/**
4952 * xmlSchemaIsBlank:
4953 * @str: a string
4954 * @len: the length of the string or -1
4955 *
4956 * Check if a string is ignorable
4957 *
4958 * Returns 1 if the string is NULL or made of blanks chars, 0 otherwise
4959 */
4960static int
4961xmlSchemaIsBlank(xmlChar * str, int len)
4962{
4963 if (str == NULL((void*)0))
4964 return (1);
4965 if (len < 0) {
4966 while (*str != 0) {
4967 if (!(IS_BLANK_CH(*str)(((*str) == 0x20) || ((0x9 <= (*str)) && ((*str) <=
0xa)) || ((*str) == 0xd))
))
4968 return (0);
4969 str++;
4970 }
4971 } else while ((*str != 0) && (len != 0)) {
4972 if (!(IS_BLANK_CH(*str)(((*str) == 0x20) || ((0x9 <= (*str)) && ((*str) <=
0xa)) || ((*str) == 0xd))
))
4973 return (0);
4974 str++;
4975 len--;
4976 }
4977
4978 return (1);
4979}
4980
4981#define WXS_COMP_NAME(c, t)((t) (c))->name ((t) (c))->name
4982#define WXS_COMP_TNS(c, t)((t) (c))->targetNamespace ((t) (c))->targetNamespace
4983/*
4984* xmlSchemaFindRedefCompInGraph:
4985* ATTENTION TODO: This uses pointer comp. for strings.
4986*/
4987static xmlSchemaBasicItemPtr
4988xmlSchemaFindRedefCompInGraph(xmlSchemaBucketPtr bucket,
4989 xmlSchemaTypeType type,
4990 const xmlChar *name,
4991 const xmlChar *nsName)
4992{
4993 xmlSchemaBasicItemPtr ret;
4994 int i;
4995
4996 if ((bucket == NULL((void*)0)) || (name == NULL((void*)0)))
4997 return(NULL((void*)0));
4998 if ((bucket->globals == NULL((void*)0)) ||
4999 (bucket->globals->nbItems == 0))
5000 goto subschemas;
5001 /*
5002 * Search in global components.
5003 */
5004 for (i = 0; i < bucket->globals->nbItems; i++) {
5005 ret = bucket->globals->items[i];
5006 if (ret->type == type) {
5007 switch (type) {
5008 case XML_SCHEMA_TYPE_COMPLEX:
5009 case XML_SCHEMA_TYPE_SIMPLE:
5010 if ((WXS_COMP_NAME(ret, xmlSchemaTypePtr)((xmlSchemaTypePtr) (ret))->name == name) &&
5011 (WXS_COMP_TNS(ret, xmlSchemaTypePtr)((xmlSchemaTypePtr) (ret))->targetNamespace ==
5012 nsName))
5013 {
5014 return(ret);
5015 }
5016 break;
5017 case XML_SCHEMA_TYPE_GROUP:
5018 if ((WXS_COMP_NAME(ret,((xmlSchemaModelGroupDefPtr) (ret))->name
5019 xmlSchemaModelGroupDefPtr)((xmlSchemaModelGroupDefPtr) (ret))->name == name) &&
5020 (WXS_COMP_TNS(ret,((xmlSchemaModelGroupDefPtr) (ret))->targetNamespace
5021 xmlSchemaModelGroupDefPtr)((xmlSchemaModelGroupDefPtr) (ret))->targetNamespace == nsName))
5022 {
5023 return(ret);
5024 }
5025 break;
5026 case XML_SCHEMA_TYPE_ATTRIBUTEGROUP:
5027 if ((WXS_COMP_NAME(ret,((xmlSchemaAttributeGroupPtr) (ret))->name
5028 xmlSchemaAttributeGroupPtr)((xmlSchemaAttributeGroupPtr) (ret))->name == name) &&
5029 (WXS_COMP_TNS(ret,((xmlSchemaAttributeGroupPtr) (ret))->targetNamespace
5030 xmlSchemaAttributeGroupPtr)((xmlSchemaAttributeGroupPtr) (ret))->targetNamespace == nsName))
5031 {
5032 return(ret);
5033 }
5034 break;
5035 default:
5036 /* Should not be hit. */
5037 return(NULL((void*)0));
5038 }
5039 }
5040 }
5041subschemas:
5042 /*
5043 * Process imported/included schemas.
5044 */
5045 if (bucket->relations != NULL((void*)0)) {
5046 xmlSchemaSchemaRelationPtr rel = bucket->relations;
5047
5048 /*
5049 * TODO: Marking the bucket will not avoid multiple searches
5050 * in the same schema, but avoids at least circularity.
5051 */
5052 bucket->flags |= XML_SCHEMA_BUCKET_MARKED1<<0;
5053 do {
5054 if ((rel->bucket != NULL((void*)0)) &&
5055 ((rel->bucket->flags & XML_SCHEMA_BUCKET_MARKED1<<0) == 0)) {
5056 ret = xmlSchemaFindRedefCompInGraph(rel->bucket,
5057 type, name, nsName);
5058 if (ret != NULL((void*)0))
5059 return(ret);
5060 }
5061 rel = rel->next;
5062 } while (rel != NULL((void*)0));
5063 bucket->flags ^= XML_SCHEMA_BUCKET_MARKED1<<0;
5064 }
5065 return(NULL((void*)0));
5066}
5067
5068/**
5069 * xmlSchemaAddNotation:
5070 * @ctxt: a schema parser context
5071 * @schema: the schema being built
5072 * @name: the item name
5073 *
5074 * Add an XML schema annotation declaration
5075 * *WARNING* this interface is highly subject to change
5076 *
5077 * Returns the new structure or NULL in case of error
5078 */
5079static xmlSchemaNotationPtr
5080xmlSchemaAddNotation(xmlSchemaParserCtxtPtr ctxt, xmlSchemaPtr schema,
5081 const xmlChar *name, const xmlChar *nsName,
5082 xmlNodePtr node ATTRIBUTE_UNUSED__attribute__((unused)))
5083{
5084 xmlSchemaNotationPtr ret = NULL((void*)0);
5085
5086 if ((ctxt == NULL((void*)0)) || (schema == NULL((void*)0)) || (name == NULL((void*)0)))
5087 return (NULL((void*)0));
5088
5089 ret = (xmlSchemaNotationPtr) xmlMalloc(sizeof(xmlSchemaNotation));
5090 if (ret == NULL((void*)0)) {
5091 xmlSchemaPErrMemory(ctxt, "add annotation", NULL((void*)0));
5092 return (NULL((void*)0));
5093 }
5094 memset(ret, 0, sizeof(xmlSchemaNotation));
5095 ret->type = XML_SCHEMA_TYPE_NOTATION;
5096 ret->name = name;
5097 ret->targetNamespace = nsName;
5098 /* TODO: do we need the node to be set?
5099 * ret->node = node;*/
5100 WXS_ADD_GLOBAL(ctxt, ret)do { if (xmlSchemaAddItemSize(&(((ctxt))->constructor->
bucket->globals), 5, ret) < 0) { xmlFree(ret); ret = ((
void*)0); } } while (0)
;
5101 return (ret);
5102}
5103
5104/**
5105 * xmlSchemaAddAttribute:
5106 * @ctxt: a schema parser context
5107 * @schema: the schema being built
5108 * @name: the item name
5109 * @namespace: the namespace
5110 *
5111 * Add an XML schema Attribute declaration
5112 * *WARNING* this interface is highly subject to change
5113 *
5114 * Returns the new structure or NULL in case of error
5115 */
5116static xmlSchemaAttributePtr
5117xmlSchemaAddAttribute(xmlSchemaParserCtxtPtr ctxt, xmlSchemaPtr schema,
5118 const xmlChar * name, const xmlChar * nsName,
5119 xmlNodePtr node, int topLevel)
5120{
5121 xmlSchemaAttributePtr ret = NULL((void*)0);
5122
5123 if ((ctxt == NULL((void*)0)) || (schema == NULL((void*)0)))
5124 return (NULL((void*)0));
5125
5126 ret = (xmlSchemaAttributePtr) xmlMalloc(sizeof(xmlSchemaAttribute));
5127 if (ret == NULL((void*)0)) {
5128 xmlSchemaPErrMemory(ctxt, "allocating attribute", NULL((void*)0));
5129 return (NULL((void*)0));
5130 }
5131 memset(ret, 0, sizeof(xmlSchemaAttribute));
5132 ret->type = XML_SCHEMA_TYPE_ATTRIBUTE;
5133 ret->node = node;
5134 ret->name = name;
5135 ret->targetNamespace = nsName;
5136
5137 if (topLevel)
5138 WXS_ADD_GLOBAL(ctxt, ret)do { if (xmlSchemaAddItemSize(&(((ctxt))->constructor->
bucket->globals), 5, ret) < 0) { xmlFree(ret); ret = ((
void*)0); } } while (0)
;
5139 else
5140 WXS_ADD_LOCAL(ctxt, ret)do { if (xmlSchemaAddItemSize(&(((ctxt))->constructor->
bucket->locals), 10, ret) < 0) { xmlFree(ret); ret = ((
void*)0); } } while (0)
;
5141 WXS_ADD_PENDING(ctxt, ret)xmlSchemaAddItemSize(&((ctxt)->constructor->pending
), 10, ret)
;
5142 return (ret);
5143}
5144
5145/**
5146 * xmlSchemaAddAttributeUse:
5147 * @ctxt: a schema parser context
5148 * @schema: the schema being built
5149 * @name: the item name
5150 * @namespace: the namespace
5151 *
5152 * Add an XML schema Attribute declaration
5153 * *WARNING* this interface is highly subject to change
5154 *
5155 * Returns the new structure or NULL in case of error
5156 */
5157static xmlSchemaAttributeUsePtr
5158xmlSchemaAddAttributeUse(xmlSchemaParserCtxtPtr pctxt,
5159 xmlNodePtr node)
5160{
5161 xmlSchemaAttributeUsePtr ret = NULL((void*)0);
5162
5163 if (pctxt == NULL((void*)0))
5164 return (NULL((void*)0));
5165
5166 ret = (xmlSchemaAttributeUsePtr) xmlMalloc(sizeof(xmlSchemaAttributeUse));
5167 if (ret == NULL((void*)0)) {
5168 xmlSchemaPErrMemory(pctxt, "allocating attribute", NULL((void*)0));
5169 return (NULL((void*)0));
5170 }
5171 memset(ret, 0, sizeof(xmlSchemaAttributeUse));
5172 ret->type = XML_SCHEMA_TYPE_ATTRIBUTE_USE;
5173 ret->node = node;
5174
5175 WXS_ADD_LOCAL(pctxt, ret)do { if (xmlSchemaAddItemSize(&(((pctxt))->constructor
->bucket->locals), 10, ret) < 0) { xmlFree(ret); ret
= ((void*)0); } } while (0)
;
5176 return (ret);
5177}
5178
5179/*
5180* xmlSchemaAddRedef:
5181*
5182* Adds a redefinition information. This is used at a later stage to:
5183* resolve references to the redefined components and to check constraints.
5184*/
5185static xmlSchemaRedefPtr
5186xmlSchemaAddRedef(xmlSchemaParserCtxtPtr pctxt,
5187 xmlSchemaBucketPtr targetBucket,
5188 void *item,
5189 const xmlChar *refName,
5190 const xmlChar *refTargetNs)
5191{
5192 xmlSchemaRedefPtr ret;
5193
5194 ret = (xmlSchemaRedefPtr)
5195 xmlMalloc(sizeof(xmlSchemaRedef));
5196 if (ret == NULL((void*)0)) {
5197 xmlSchemaPErrMemory(pctxt,
5198 "allocating redefinition info", NULL((void*)0));
5199 return (NULL((void*)0));
5200 }
5201 memset(ret, 0, sizeof(xmlSchemaRedef));
5202 ret->item = item;
5203 ret->targetBucket = targetBucket;
5204 ret->refName = refName;
5205 ret->refTargetNs = refTargetNs;
5206 if (WXS_CONSTRUCTOR(pctxt)(pctxt)->constructor->redefs == NULL((void*)0))
5207 WXS_CONSTRUCTOR(pctxt)(pctxt)->constructor->redefs = ret;
5208 else
5209 WXS_CONSTRUCTOR(pctxt)(pctxt)->constructor->lastRedef->next = ret;
5210 WXS_CONSTRUCTOR(pctxt)(pctxt)->constructor->lastRedef = ret;
5211
5212 return (ret);
5213}
5214
5215/**
5216 * xmlSchemaAddAttributeGroupDefinition:
5217 * @ctxt: a schema parser context
5218 * @schema: the schema being built
5219 * @name: the item name
5220 * @nsName: the target namespace
5221 * @node: the corresponding node
5222 *
5223 * Add an XML schema Attribute Group definition.
5224 *
5225 * Returns the new structure or NULL in case of error
5226 */
5227static xmlSchemaAttributeGroupPtr
5228xmlSchemaAddAttributeGroupDefinition(xmlSchemaParserCtxtPtr pctxt,
5229 xmlSchemaPtr schema ATTRIBUTE_UNUSED__attribute__((unused)),
5230 const xmlChar *name,
5231 const xmlChar *nsName,
5232 xmlNodePtr node)
5233{
5234 xmlSchemaAttributeGroupPtr ret = NULL((void*)0);
5235
5236 if ((pctxt == NULL((void*)0)) || (name == NULL((void*)0)))
5237 return (NULL((void*)0));
5238
5239 ret = (xmlSchemaAttributeGroupPtr)
5240 xmlMalloc(sizeof(xmlSchemaAttributeGroup));
5241 if (ret == NULL((void*)0)) {
5242 xmlSchemaPErrMemory(pctxt, "allocating attribute group", NULL((void*)0));
5243 return (NULL((void*)0));
5244 }
5245 memset(ret, 0, sizeof(xmlSchemaAttributeGroup));
5246 ret->type = XML_SCHEMA_TYPE_ATTRIBUTEGROUP;
5247 ret->name = name;
5248 ret->targetNamespace = nsName;
5249 ret->node = node;
5250
5251 /* TODO: Remove the flag. */
5252 ret->flags |= XML_SCHEMAS_ATTRGROUP_GLOBAL1 << 1;
5253 if (pctxt->isRedefine) {
5254 pctxt->redef = xmlSchemaAddRedef(pctxt, pctxt->redefined,
5255 ret, name, nsName);
5256 if (pctxt->redef == NULL((void*)0)) {
5257 xmlFree(ret);
5258 return(NULL((void*)0));
5259 }
5260 pctxt->redefCounter = 0;
5261 }
5262 WXS_ADD_GLOBAL(pctxt, ret)do { if (xmlSchemaAddItemSize(&(((pctxt))->constructor
->bucket->globals), 5, ret) < 0) { xmlFree(ret); ret
= ((void*)0); } } while (0)
;
5263 WXS_ADD_PENDING(pctxt, ret)xmlSchemaAddItemSize(&((pctxt)->constructor->pending
), 10, ret)
;
5264 return (ret);
5265}
5266
5267/**
5268 * xmlSchemaAddElement:
5269 * @ctxt: a schema parser context
5270 * @schema: the schema being built
5271 * @name: the type name
5272 * @namespace: the type namespace
5273 *
5274 * Add an XML schema Element declaration
5275 * *WARNING* this interface is highly subject to change
5276 *
5277 * Returns the new structure or NULL in case of error
5278 */
5279static xmlSchemaElementPtr
5280xmlSchemaAddElement(xmlSchemaParserCtxtPtr ctxt,
5281 const xmlChar * name, const xmlChar * nsName,
5282 xmlNodePtr node, int topLevel)
5283{
5284 xmlSchemaElementPtr ret = NULL((void*)0);
5285
5286 if ((ctxt == NULL((void*)0)) || (name == NULL((void*)0)))
5287 return (NULL((void*)0));
5288
5289 ret = (xmlSchemaElementPtr) xmlMalloc(sizeof(xmlSchemaElement));
5290 if (ret == NULL((void*)0)) {
5291 xmlSchemaPErrMemory(ctxt, "allocating element", NULL((void*)0));
5292 return (NULL((void*)0));
5293 }
5294 memset(ret, 0, sizeof(xmlSchemaElement));
5295 ret->type = XML_SCHEMA_TYPE_ELEMENT;
5296 ret->name = name;
5297 ret->targetNamespace = nsName;
5298 ret->node = node;
5299
5300 if (topLevel)
5301 WXS_ADD_GLOBAL(ctxt, ret)do { if (xmlSchemaAddItemSize(&(((ctxt))->constructor->
bucket->globals), 5, ret) < 0) { xmlFree(ret); ret = ((
void*)0); } } while (0)
;
5302 else
5303 WXS_ADD_LOCAL(ctxt, ret)do { if (xmlSchemaAddItemSize(&(((ctxt))->constructor->
bucket->locals), 10, ret) < 0) { xmlFree(ret); ret = ((
void*)0); } } while (0)
;
5304 WXS_ADD_PENDING(ctxt, ret)xmlSchemaAddItemSize(&((ctxt)->constructor->pending
), 10, ret)
;
5305 return (ret);
5306}
5307
5308/**
5309 * xmlSchemaAddType:
5310 * @ctxt: a schema parser context
5311 * @schema: the schema being built
5312 * @name: the item name
5313 * @namespace: the namespace
5314 *
5315 * Add an XML schema item
5316 * *WARNING* this interface is highly subject to change
5317 *
5318 * Returns the new structure or NULL in case of error
5319 */
5320static xmlSchemaTypePtr
5321xmlSchemaAddType(xmlSchemaParserCtxtPtr ctxt, xmlSchemaPtr schema,
5322 xmlSchemaTypeType type,
5323 const xmlChar * name, const xmlChar * nsName,
5324 xmlNodePtr node, int topLevel)
5325{
5326 xmlSchemaTypePtr ret = NULL((void*)0);
5327
5328 if ((ctxt == NULL((void*)0)) || (schema == NULL((void*)0)))
5329 return (NULL((void*)0));
5330
5331 ret = (xmlSchemaTypePtr) xmlMalloc(sizeof(xmlSchemaType));
5332 if (ret == NULL((void*)0)) {
5333 xmlSchemaPErrMemory(ctxt, "allocating type", NULL((void*)0));
5334 return (NULL((void*)0));
5335 }
5336 memset(ret, 0, sizeof(xmlSchemaType));
5337 ret->type = type;
5338 ret->name = name;
5339 ret->targetNamespace = nsName;
5340 ret->node = node;
5341 if (topLevel) {
5342 if (ctxt->isRedefine) {
5343 ctxt->redef = xmlSchemaAddRedef(ctxt, ctxt->redefined,
5344 ret, name, nsName);
5345 if (ctxt->redef == NULL((void*)0)) {
5346 xmlFree(ret);
5347 return(NULL((void*)0));
5348 }
5349 ctxt->redefCounter = 0;
5350 }
5351 WXS_ADD_GLOBAL(ctxt, ret)do { if (xmlSchemaAddItemSize(&(((ctxt))->constructor->
bucket->globals), 5, ret) < 0) { xmlFree(ret); ret = ((
void*)0); } } while (0)
;
5352 } else
5353 WXS_ADD_LOCAL(ctxt, ret)do { if (xmlSchemaAddItemSize(&(((ctxt))->constructor->
bucket->locals), 10, ret) < 0) { xmlFree(ret); ret = ((
void*)0); } } while (0)
;
5354 WXS_ADD_PENDING(ctxt, ret)xmlSchemaAddItemSize(&((ctxt)->constructor->pending
), 10, ret)
;
5355 return (ret);
5356}
5357
5358static xmlSchemaQNameRefPtr
5359xmlSchemaNewQNameRef(xmlSchemaParserCtxtPtr pctxt,
5360 xmlSchemaTypeType refType,
5361 const xmlChar *refName,
5362 const xmlChar *refNs)
5363{
5364 xmlSchemaQNameRefPtr ret;
5365
5366 ret = (xmlSchemaQNameRefPtr)
5367 xmlMalloc(sizeof(xmlSchemaQNameRef));
5368 if (ret == NULL((void*)0)) {
5369 xmlSchemaPErrMemory(pctxt,
5370 "allocating QName reference item", NULL((void*)0));
5371 return (NULL((void*)0));
5372 }
5373 ret->node = NULL((void*)0);
5374 ret->type = XML_SCHEMA_EXTRA_QNAMEREF;
5375 ret->name = refName;
5376 ret->targetNamespace = refNs;
5377 ret->item = NULL((void*)0);
5378 ret->itemType = refType;
5379 /*
5380 * Store the reference item in the schema.
5381 */
5382 WXS_ADD_LOCAL(pctxt, ret)do { if (xmlSchemaAddItemSize(&(((pctxt))->constructor
->bucket->locals), 10, ret) < 0) { xmlFree(ret); ret
= ((void*)0); } } while (0)
;
5383 return (ret);
5384}
5385
5386static xmlSchemaAttributeUseProhibPtr
5387xmlSchemaAddAttributeUseProhib(xmlSchemaParserCtxtPtr pctxt)
5388{
5389 xmlSchemaAttributeUseProhibPtr ret;
5390
5391 ret = (xmlSchemaAttributeUseProhibPtr)
5392 xmlMalloc(sizeof(xmlSchemaAttributeUseProhib));
5393 if (ret == NULL((void*)0)) {
5394 xmlSchemaPErrMemory(pctxt,
5395 "allocating attribute use prohibition", NULL((void*)0));
5396 return (NULL((void*)0));
5397 }
5398 memset(ret, 0, sizeof(xmlSchemaAttributeUseProhib));
5399 ret->type = XML_SCHEMA_EXTRA_ATTR_USE_PROHIB;
5400 WXS_ADD_LOCAL(pctxt, ret)do { if (xmlSchemaAddItemSize(&(((pctxt))->constructor
->bucket->locals), 10, ret) < 0) { xmlFree(ret); ret
= ((void*)0); } } while (0)
;
5401 return (ret);
5402}
5403
5404
5405/**
5406 * xmlSchemaAddModelGroup:
5407 * @ctxt: a schema parser context
5408 * @schema: the schema being built
5409 * @type: the "compositor" type of the model group
5410 * @node: the node in the schema doc
5411 *
5412 * Adds a schema model group
5413 * *WARNING* this interface is highly subject to change
5414 *
5415 * Returns the new structure or NULL in case of error
5416 */
5417static xmlSchemaModelGroupPtr
5418xmlSchemaAddModelGroup(xmlSchemaParserCtxtPtr ctxt,
5419 xmlSchemaPtr schema,
5420 xmlSchemaTypeType type,
5421 xmlNodePtr node)
5422{
5423 xmlSchemaModelGroupPtr ret = NULL((void*)0);
5424
5425 if ((ctxt == NULL((void*)0)) || (schema == NULL((void*)0)))
5426 return (NULL((void*)0));
5427
5428 ret = (xmlSchemaModelGroupPtr)
5429 xmlMalloc(sizeof(xmlSchemaModelGroup));
5430 if (ret == NULL((void*)0)) {
5431 xmlSchemaPErrMemory(ctxt, "allocating model group component",
5432 NULL((void*)0));
5433 return (NULL((void*)0));
5434 }
5435 memset(ret, 0, sizeof(xmlSchemaModelGroup));
5436 ret->type = type;
5437 ret->node = node;
5438 WXS_ADD_LOCAL(ctxt, ret)do { if (xmlSchemaAddItemSize(&(((ctxt))->constructor->
bucket->locals), 10, ret) < 0) { xmlFree(ret); ret = ((
void*)0); } } while (0)
;
5439 if ((type == XML_SCHEMA_TYPE_SEQUENCE) ||
5440 (type == XML_SCHEMA_TYPE_CHOICE))
5441 WXS_ADD_PENDING(ctxt, ret)xmlSchemaAddItemSize(&((ctxt)->constructor->pending
), 10, ret)
;
5442 return (ret);
5443}
5444
5445
5446/**
5447 * xmlSchemaAddParticle:
5448 * @ctxt: a schema parser context
5449 * @schema: the schema being built
5450 * @node: the corresponding node in the schema doc
5451 * @min: the minOccurs
5452 * @max: the maxOccurs
5453 *
5454 * Adds an XML schema particle component.
5455 * *WARNING* this interface is highly subject to change
5456 *
5457 * Returns the new structure or NULL in case of error
5458 */
5459static xmlSchemaParticlePtr
5460xmlSchemaAddParticle(xmlSchemaParserCtxtPtr ctxt,
5461 xmlNodePtr node, int min, int max)
5462{
5463 xmlSchemaParticlePtr ret = NULL((void*)0);
5464 if (ctxt == NULL((void*)0))
5465 return (NULL((void*)0));
5466
5467 ret = (xmlSchemaParticlePtr)
5468 xmlMalloc(sizeof(xmlSchemaParticle));
5469 if (ret == NULL((void*)0)) {
5470 xmlSchemaPErrMemory(ctxt, "allocating particle component",
5471 NULL((void*)0));
5472 return (NULL((void*)0));
5473 }
5474 ret->type = XML_SCHEMA_TYPE_PARTICLE;
5475 ret->annot = NULL((void*)0);
5476 ret->node = node;
5477 ret->minOccurs = min;
5478 ret->maxOccurs = max;
5479 ret->next = NULL((void*)0);
5480 ret->children = NULL((void*)0);
5481
5482 WXS_ADD_LOCAL(ctxt, ret)do { if (xmlSchemaAddItemSize(&(((ctxt))->constructor->
bucket->locals), 10, ret) < 0) { xmlFree(ret); ret = ((
void*)0); } } while (0)
;
5483 /*
5484 * Note that addition to pending components will be done locally
5485 * to the specific parsing function, since the most particles
5486 * need not to be fixed up (i.e. the reference to be resolved).
5487 * REMOVED: WXS_ADD_PENDING(ctxt, ret);
5488 */
5489 return (ret);
5490}
5491
5492/**
5493 * xmlSchemaAddModelGroupDefinition:
5494 * @ctxt: a schema validation context
5495 * @schema: the schema being built
5496 * @name: the group name
5497 *
5498 * Add an XML schema Group definition
5499 *
5500 * Returns the new structure or NULL in case of error
5501 */
5502static xmlSchemaModelGroupDefPtr
5503xmlSchemaAddModelGroupDefinition(xmlSchemaParserCtxtPtr ctxt,
5504 xmlSchemaPtr schema,
5505 const xmlChar *name,
5506 const xmlChar *nsName,
5507 xmlNodePtr node)
5508{
5509 xmlSchemaModelGroupDefPtr ret = NULL((void*)0);
5510
5511 if ((ctxt == NULL((void*)0)) || (schema == NULL((void*)0)) || (name == NULL((void*)0)))
5512 return (NULL((void*)0));
5513
5514 ret = (xmlSchemaModelGroupDefPtr)
5515 xmlMalloc(sizeof(xmlSchemaModelGroupDef));
5516 if (ret == NULL((void*)0)) {
5517 xmlSchemaPErrMemory(ctxt, "adding group", NULL((void*)0));
5518 return (NULL((void*)0));
5519 }
5520 memset(ret, 0, sizeof(xmlSchemaModelGroupDef));
5521 ret->name = name;
5522 ret->type = XML_SCHEMA_TYPE_GROUP;
5523 ret->node = node;
5524 ret->targetNamespace = nsName;
5525
5526 if (ctxt->isRedefine) {
5527 ctxt->redef = xmlSchemaAddRedef(ctxt, ctxt->redefined,
5528 ret, name, nsName);
5529 if (ctxt->redef == NULL((void*)0)) {
5530 xmlFree(ret);
5531 return(NULL((void*)0));
5532 }
5533 ctxt->redefCounter = 0;
5534 }
5535 WXS_ADD_GLOBAL(ctxt, ret)do { if (xmlSchemaAddItemSize(&(((ctxt))->constructor->
bucket->globals), 5, ret) < 0) { xmlFree(ret); ret = ((
void*)0); } } while (0)
;
5536 WXS_ADD_PENDING(ctxt, ret)xmlSchemaAddItemSize(&((ctxt)->constructor->pending
), 10, ret)
;
5537 return (ret);
5538}
5539
5540/**
5541 * xmlSchemaNewWildcardNs:
5542 * @ctxt: a schema validation context
5543 *
5544 * Creates a new wildcard namespace constraint.
5545 *
5546 * Returns the new structure or NULL in case of error
5547 */
5548static xmlSchemaWildcardNsPtr
5549xmlSchemaNewWildcardNsConstraint(xmlSchemaParserCtxtPtr ctxt)
5550{
5551 xmlSchemaWildcardNsPtr ret;
5552
5553 ret = (xmlSchemaWildcardNsPtr)
5554 xmlMalloc(sizeof(xmlSchemaWildcardNs));
5555 if (ret == NULL((void*)0)) {
5556 xmlSchemaPErrMemory(ctxt, "creating wildcard namespace constraint", NULL((void*)0));
5557 return (NULL((void*)0));
5558 }
5559 ret->value = NULL((void*)0);
5560 ret->next = NULL((void*)0);
5561 return (ret);
5562}
5563
5564static xmlSchemaIDCPtr
5565xmlSchemaAddIDC(xmlSchemaParserCtxtPtr ctxt, xmlSchemaPtr schema,
5566 const xmlChar *name, const xmlChar *nsName,
5567 int category, xmlNodePtr node)
5568{
5569 xmlSchemaIDCPtr ret = NULL((void*)0);
5570
5571 if ((ctxt == NULL((void*)0)) || (schema == NULL((void*)0)) || (name == NULL((void*)0)))
5572 return (NULL((void*)0));
5573
5574 ret = (xmlSchemaIDCPtr) xmlMalloc(sizeof(xmlSchemaIDC));
5575 if (ret == NULL((void*)0)) {
5576 xmlSchemaPErrMemory(ctxt,
5577 "allocating an identity-constraint definition", NULL((void*)0));
5578 return (NULL((void*)0));
5579 }
5580 memset(ret, 0, sizeof(xmlSchemaIDC));
5581 /* The target namespace of the parent element declaration. */
5582 ret->targetNamespace = nsName;
5583 ret->name = name;
5584 ret->type = category;
5585 ret->node = node;
5586
5587 WXS_ADD_GLOBAL(ctxt, ret)do { if (xmlSchemaAddItemSize(&(((ctxt))->constructor->
bucket->globals), 5, ret) < 0) { xmlFree(ret); ret = ((
void*)0); } } while (0)
;
5588 /*
5589 * Only keyrefs need to be fixup up.
5590 */
5591 if (category == XML_SCHEMA_TYPE_IDC_KEYREF)
5592 WXS_ADD_PENDING(ctxt, ret)xmlSchemaAddItemSize(&((ctxt)->constructor->pending
), 10, ret)
;
5593 return (ret);
5594}
5595
5596/**
5597 * xmlSchemaAddWildcard:
5598 * @ctxt: a schema validation context
5599 * @schema: a schema
5600 *
5601 * Adds a wildcard.
5602 * It corresponds to a xsd:anyAttribute and xsd:any.
5603 *
5604 * Returns the new structure or NULL in case of error
5605 */
5606static xmlSchemaWildcardPtr
5607xmlSchemaAddWildcard(xmlSchemaParserCtxtPtr ctxt, xmlSchemaPtr schema,
5608 xmlSchemaTypeType type, xmlNodePtr node)
5609{
5610 xmlSchemaWildcardPtr ret = NULL((void*)0);
5611
5612 if ((ctxt == NULL((void*)0)) || (schema == NULL((void*)0)))
5613 return (NULL((void*)0));
5614
5615 ret = (xmlSchemaWildcardPtr) xmlMalloc(sizeof(xmlSchemaWildcard));
5616 if (ret == NULL((void*)0)) {
5617 xmlSchemaPErrMemory(ctxt, "adding wildcard", NULL((void*)0));
5618 return (NULL((void*)0));
5619 }
5620 memset(ret, 0, sizeof(xmlSchemaWildcard));
5621 ret->type = type;
5622 ret->node = node;
5623 WXS_ADD_LOCAL(ctxt, ret)do { if (xmlSchemaAddItemSize(&(((ctxt))->constructor->
bucket->locals), 10, ret) < 0) { xmlFree(ret); ret = ((
void*)0); } } while (0)
;
5624 return (ret);
5625}
5626
5627static void
5628xmlSchemaSubstGroupFree(xmlSchemaSubstGroupPtr group)
5629{
5630 if (group == NULL((void*)0))
5631 return;
5632 if (group->members != NULL((void*)0))
5633 xmlSchemaItemListFree(group->members);
5634 xmlFree(group);
5635}
5636
5637static void
5638xmlSchemaSubstGroupFreeEntry(void *group, const xmlChar *name ATTRIBUTE_UNUSED__attribute__((unused)))
5639{
5640 xmlSchemaSubstGroupFree((xmlSchemaSubstGroupPtr) group);
5641}
5642
5643static xmlSchemaSubstGroupPtr
5644xmlSchemaSubstGroupAdd(xmlSchemaParserCtxtPtr pctxt,
5645 xmlSchemaElementPtr head)
5646{
5647 xmlSchemaSubstGroupPtr ret;
5648
5649 /* Init subst group hash. */
5650 if (WXS_SUBST_GROUPS(pctxt)((pctxt))->constructor->substGroups == NULL((void*)0)) {
5651 WXS_SUBST_GROUPS(pctxt)((pctxt))->constructor->substGroups = xmlHashCreateDict(10, pctxt->dict);
5652 if (WXS_SUBST_GROUPS(pctxt)((pctxt))->constructor->substGroups == NULL((void*)0))
5653 return(NULL((void*)0));
5654 }
5655 /* Create a new substitution group. */
5656 ret = (xmlSchemaSubstGroupPtr) xmlMalloc(sizeof(xmlSchemaSubstGroup));
5657 if (ret == NULL((void*)0)) {
5658 xmlSchemaPErrMemory(NULL((void*)0),
5659 "allocating a substitution group container", NULL((void*)0));
5660 return(NULL((void*)0));
5661 }
5662 memset(ret, 0, sizeof(xmlSchemaSubstGroup));
5663 ret->head = head;
5664 /* Create list of members. */
5665 ret->members = xmlSchemaItemListCreate();
5666 if (ret->members == NULL((void*)0)) {
5667 xmlSchemaSubstGroupFree(ret);
5668 return(NULL((void*)0));
5669 }
5670 /* Add subst group to hash. */
5671 if (xmlHashAddEntry2(WXS_SUBST_GROUPS(pctxt)((pctxt))->constructor->substGroups,
5672 head->name, head->targetNamespace, ret) != 0) {
5673 PERROR_INT("xmlSchemaSubstGroupAdd",xmlSchemaInternalErr((xmlSchemaAbstractCtxtPtr) pctxt, "xmlSchemaSubstGroupAdd"
, "failed to add a new substitution container");
5674 "failed to add a new substitution container")xmlSchemaInternalErr((xmlSchemaAbstractCtxtPtr) pctxt, "xmlSchemaSubstGroupAdd"
, "failed to add a new substitution container");
;
5675 xmlSchemaSubstGroupFree(ret);
5676 return(NULL((void*)0));
5677 }
5678 return(ret);
5679}
5680
5681static xmlSchemaSubstGroupPtr
5682xmlSchemaSubstGroupGet(xmlSchemaParserCtxtPtr pctxt,
5683 xmlSchemaElementPtr head)
5684{
5685 if (WXS_SUBST_GROUPS(pctxt)((pctxt))->constructor->substGroups == NULL((void*)0))
5686 return(NULL((void*)0));
5687 return(xmlHashLookup2(WXS_SUBST_GROUPS(pctxt)((pctxt))->constructor->substGroups,
5688 head->name, head->targetNamespace));
5689
5690}
5691
5692/**
5693 * xmlSchemaAddElementSubstitutionMember:
5694 * @pctxt: a schema parser context
5695 * @head: the head of the substitution group
5696 * @member: the new member of the substitution group
5697 *
5698 * Allocate a new annotation structure.
5699 *
5700 * Returns the newly allocated structure or NULL in case or error
5701 */
5702static int
5703xmlSchemaAddElementSubstitutionMember(xmlSchemaParserCtxtPtr pctxt,
5704 xmlSchemaElementPtr head,
5705 xmlSchemaElementPtr member)
5706{
5707 xmlSchemaSubstGroupPtr substGroup = NULL((void*)0);
5708
5709 if ((pctxt == NULL((void*)0)) || (head == NULL((void*)0)) || (member == NULL((void*)0)))
5710 return (-1);
5711
5712 substGroup = xmlSchemaSubstGroupGet(pctxt, head);
5713 if (substGroup == NULL((void*)0))
5714 substGroup = xmlSchemaSubstGroupAdd(pctxt, head);
5715 if (substGroup == NULL((void*)0))
5716 return(-1);
5717 if (xmlSchemaItemListAdd(substGroup->members, member) == -1)
5718 return(-1);
5719 return(0);
5720}
5721
5722/************************************************************************
5723 * *
5724 * Utilities for parsing *
5725 * *
5726 ************************************************************************/
5727
5728/**
5729 * xmlSchemaPValAttrNodeQNameValue:
5730 * @ctxt: a schema parser context
5731 * @schema: the schema context
5732 * @ownerItem: the parent as a schema object
5733 * @value: the QName value
5734 * @uri: the resulting namespace URI if found
5735 * @local: the resulting local part if found, the attribute value otherwise
5736 *
5737 * Extracts the local name and the URI of a QName value and validates it.
5738 * This one is intended to be used on attribute values that
5739 * should resolve to schema components.
5740 *
5741 * Returns 0, in case the QName is valid, a positive error code
5742 * if not valid and -1 if an internal error occurs.
5743 */
5744static int
5745xmlSchemaPValAttrNodeQNameValue(xmlSchemaParserCtxtPtr ctxt,
5746 xmlSchemaPtr schema,
5747 xmlSchemaBasicItemPtr ownerItem,
5748 xmlAttrPtr attr,
5749 const xmlChar *value,
5750 const xmlChar **uri,
5751 const xmlChar **local)
5752{
5753 const xmlChar *pref;
5754 xmlNsPtr ns;
5755 int len, ret;
5756
5757 *uri = NULL((void*)0);
5758 *local = NULL((void*)0);
5759 ret = xmlValidateQName(value, 1);
5760 if (ret > 0) {
5761 xmlSchemaPSimpleTypeErr(ctxt,
5762 XML_SCHEMAP_S4S_ATTR_INVALID_VALUE,
5763 ownerItem, (xmlNodePtr) attr,
5764 xmlSchemaGetBuiltInType(XML_SCHEMAS_QNAME),
5765 NULL((void*)0), value, NULL((void*)0), NULL((void*)0), NULL((void*)0));
5766 *local = value;
5767 return (ctxt->err);
5768 } else if (ret < 0)
5769 return (-1);
5770
5771 if (!strchr((char *) value, ':')) {
5772 ns = xmlSearchNs(attr->doc, attr->parent, NULL((void*)0));
5773 if (ns && ns->href && ns->href[0])
5774 *uri = xmlDictLookup(ctxt->dict, ns->href, -1);
5775 else if (schema->flags & XML_SCHEMAS_INCLUDING_CONVERT_NS1 << 9) {
5776 /* TODO: move XML_SCHEMAS_INCLUDING_CONVERT_NS to the
5777 * parser context. */
5778 /*
5779 * This one takes care of included schemas with no
5780 * target namespace.
5781 */
5782 *uri = ctxt->targetNamespace;
5783 }
5784 *local = xmlDictLookup(ctxt->dict, value, -1);
5785 return (0);
5786 }
5787 /*
5788 * At this point xmlSplitQName3 has to return a local name.
5789 */
5790 *local = xmlSplitQName3(value, &len);
5791 *local = xmlDictLookup(ctxt->dict, *local, -1);
5792 pref = xmlDictLookup(ctxt->dict, value, len);
5793 ns = xmlSearchNs(attr->doc, attr->parent, pref);
5794 if (ns == NULL((void*)0)) {
5795 xmlSchemaPSimpleTypeErr(ctxt,
5796 XML_SCHEMAP_S4S_ATTR_INVALID_VALUE,
5797 ownerItem, (xmlNodePtr) attr,
5798 xmlSchemaGetBuiltInType(XML_SCHEMAS_QNAME), NULL((void*)0), value,
5799 "The value '%s' of simple type 'xs:QName' has no "
5800 "corresponding namespace declaration in scope", value, NULL((void*)0));
5801 return (ctxt->err);
5802 } else {
5803 *uri = xmlDictLookup(ctxt->dict, ns->href, -1);
5804 }
5805 return (0);
5806}
5807
5808/**
5809 * xmlSchemaPValAttrNodeQName:
5810 * @ctxt: a schema parser context
5811 * @schema: the schema context
5812 * @ownerItem: the owner as a schema object
5813 * @attr: the attribute node
5814 * @uri: the resulting namespace URI if found
5815 * @local: the resulting local part if found, the attribute value otherwise
5816 *
5817 * Extracts and validates the QName of an attribute value.
5818 * This one is intended to be used on attribute values that
5819 * should resolve to schema components.
5820 *
5821 * Returns 0, in case the QName is valid, a positive error code
5822 * if not valid and -1 if an internal error occurs.
5823 */
5824static int
5825xmlSchemaPValAttrNodeQName(xmlSchemaParserCtxtPtr ctxt,
5826 xmlSchemaPtr schema,
5827 xmlSchemaBasicItemPtr ownerItem,
5828 xmlAttrPtr attr,
5829 const xmlChar **uri,
5830 const xmlChar **local)
5831{
5832 const xmlChar *value;
5833
5834 value = xmlSchemaGetNodeContent(ctxt, (xmlNodePtr) attr);
5835 return (xmlSchemaPValAttrNodeQNameValue(ctxt, schema,
5836 ownerItem, attr, value, uri, local));
5837}
5838
5839/**
5840 * xmlSchemaPValAttrQName:
5841 * @ctxt: a schema parser context
5842 * @schema: the schema context
5843 * @ownerItem: the owner as a schema object
5844 * @ownerElem: the parent node of the attribute
5845 * @name: the name of the attribute
5846 * @uri: the resulting namespace URI if found
5847 * @local: the resulting local part if found, the attribute value otherwise
5848 *
5849 * Extracts and validates the QName of an attribute value.
5850 *
5851 * Returns 0, in case the QName is valid, a positive error code
5852 * if not valid and -1 if an internal error occurs.
5853 */
5854static int
5855xmlSchemaPValAttrQName(xmlSchemaParserCtxtPtr ctxt,
5856 xmlSchemaPtr schema,
5857 xmlSchemaBasicItemPtr ownerItem,
5858 xmlNodePtr ownerElem,
5859 const char *name,
5860 const xmlChar **uri,
5861 const xmlChar **local)
5862{
5863 xmlAttrPtr attr;
5864
5865 attr = xmlSchemaGetPropNode(ownerElem, name);
5866 if (attr == NULL((void*)0)) {
5867 *local = NULL((void*)0);
5868 *uri = NULL((void*)0);
5869 return (0);
5870 }
5871 return (xmlSchemaPValAttrNodeQName(ctxt, schema,
5872 ownerItem, attr, uri, local));
5873}
5874
5875/**
5876 * xmlSchemaPValAttrID:
5877 * @ctxt: a schema parser context
5878 *
5879 * Extracts and validates the ID of an attribute value.
5880 *
5881 * Returns 0, in case the ID is valid, a positive error code
5882 * if not valid and -1 if an internal error occurs.
5883 */
5884static int
5885xmlSchemaPValAttrNodeID(xmlSchemaParserCtxtPtr ctxt, xmlAttrPtr attr)
5886{
5887 int ret;
5888 const xmlChar *value;
5889
5890 if (attr == NULL((void*)0))
5891 return(0);
5892 value = xmlSchemaGetNodeContentNoDict((xmlNodePtr) attr);
5893 ret = xmlValidateNCName(value, 1);
5894 if (ret == 0) {
5895 /*
5896 * NOTE: the IDness might have already be declared in the DTD
5897 */
5898 if (attr->atype != XML_ATTRIBUTE_ID) {
5899 xmlIDPtr res;
5900 xmlChar *strip;
5901
5902 /*
5903 * TODO: Use xmlSchemaStrip here; it's not exported at this
5904 * moment.
5905 */
5906 strip = xmlSchemaCollapseString(value);
5907 if (strip != NULL((void*)0)) {
5908 xmlFree((xmlChar *) value);
5909 value = strip;
5910 }
5911 res = xmlAddID(NULL((void*)0), attr->doc, value, attr);
5912 if (res == NULL((void*)0)) {
5913 ret = XML_SCHEMAP_S4S_ATTR_INVALID_VALUE;
5914 xmlSchemaPSimpleTypeErr(ctxt,
5915 XML_SCHEMAP_S4S_ATTR_INVALID_VALUE,
5916 NULL((void*)0), (xmlNodePtr) attr,
5917 xmlSchemaGetBuiltInType(XML_SCHEMAS_ID),
5918 NULL((void*)0), NULL((void*)0), "Duplicate value '%s' of simple "
5919 "type 'xs:ID'", value, NULL((void*)0));
5920 } else
5921 attr->atype = XML_ATTRIBUTE_ID;
5922 }
5923 } else if (ret > 0) {
5924 ret = XML_SCHEMAP_S4S_ATTR_INVALID_VALUE;
5925 xmlSchemaPSimpleTypeErr(ctxt,
5926 XML_SCHEMAP_S4S_ATTR_INVALID_VALUE,
5927 NULL((void*)0), (xmlNodePtr) attr,
5928 xmlSchemaGetBuiltInType(XML_SCHEMAS_ID),
5929 NULL((void*)0), NULL((void*)0), "The value '%s' of simple type 'xs:ID' is "
5930 "not a valid 'xs:NCName'",
5931 value, NULL((void*)0));
5932 }
5933 if (value != NULL((void*)0))
5934 xmlFree((xmlChar *)value);
5935
5936 return (ret);
5937}
5938
5939static int
5940xmlSchemaPValAttrID(xmlSchemaParserCtxtPtr ctxt,
5941 xmlNodePtr ownerElem,
5942 const xmlChar *name)
5943{
5944 xmlAttrPtr attr;
5945
5946 attr = xmlSchemaGetPropNode(ownerElem, (const char *) name);
5947 if (attr == NULL((void*)0))
5948 return(0);
5949 return(xmlSchemaPValAttrNodeID(ctxt, attr));
5950
5951}
5952
5953/**
5954 * xmlGetMaxOccurs:
5955 * @ctxt: a schema validation context
5956 * @node: a subtree containing XML Schema information
5957 *
5958 * Get the maxOccurs property
5959 *
5960 * Returns the default if not found, or the value
5961 */
5962static int
5963xmlGetMaxOccurs(xmlSchemaParserCtxtPtr ctxt, xmlNodePtr node,
5964 int min, int max, int def, const char *expected)
5965{
5966 const xmlChar *val, *cur;
5967 int ret = 0;
5968 xmlAttrPtr attr;
5969
5970 attr = xmlSchemaGetPropNode(node, "maxOccurs");
5971 if (attr == NULL((void*)0))
5972 return (def);
5973 val = xmlSchemaGetNodeContent(ctxt, (xmlNodePtr) attr);
5974 if (val == NULL((void*)0))
5975 return (def);
5976
5977 if (xmlStrEqual(val, (const xmlChar *) "unbounded")) {
5978 if (max != UNBOUNDED(1 << 30)) {
5979 xmlSchemaPSimpleTypeErr(ctxt,
5980 XML_SCHEMAP_S4S_ATTR_INVALID_VALUE,
5981 /* XML_SCHEMAP_INVALID_MINOCCURS, */
5982 NULL((void*)0), (xmlNodePtr) attr, NULL((void*)0), expected,
5983 val, NULL((void*)0), NULL((void*)0), NULL((void*)0));
5984 return (def);
5985 } else
5986 return (UNBOUNDED(1 << 30)); /* encoding it with -1 might be another option */
5987 }
5988
5989 cur = val;
5990 while (IS_BLANK_CH(*cur)(((*cur) == 0x20) || ((0x9 <= (*cur)) && ((*cur) <=
0xa)) || ((*cur) == 0xd))
)
5991 cur++;
5992 if (*cur == 0) {
5993 xmlSchemaPSimpleTypeErr(ctxt,
5994 XML_SCHEMAP_S4S_ATTR_INVALID_VALUE,
5995 /* XML_SCHEMAP_INVALID_MINOCCURS, */
5996 NULL((void*)0), (xmlNodePtr) attr, NULL((void*)0), expected,
5997 val, NULL((void*)0), NULL((void*)0), NULL((void*)0));
5998 return (def);
5999 }
6000 while ((*cur >= '0') && (*cur <= '9')) {
6001 if (ret > INT_MAX2147483647 / 10) {
6002 ret = INT_MAX2147483647;
6003 } else {
6004 int digit = *cur - '0';
6005 ret *= 10;
6006 if (ret > INT_MAX2147483647 - digit)
6007 ret = INT_MAX2147483647;
6008 else
6009 ret += digit;
6010 }
6011 cur++;
6012 }
6013 while (IS_BLANK_CH(*cur)(((*cur) == 0x20) || ((0x9 <= (*cur)) && ((*cur) <=
0xa)) || ((*cur) == 0xd))
)
6014 cur++;
6015 /*
6016 * TODO: Restrict the maximal value to Integer.
6017 */
6018 if ((*cur != 0) || (ret < min) || ((max != -1) && (ret > max))) {
6019 xmlSchemaPSimpleTypeErr(ctxt,
6020 XML_SCHEMAP_S4S_ATTR_INVALID_VALUE,
6021 /* XML_SCHEMAP_INVALID_MINOCCURS, */
6022 NULL((void*)0), (xmlNodePtr) attr, NULL((void*)0), expected,
6023 val, NULL((void*)0), NULL((void*)0), NULL((void*)0));
6024 return (def);
6025 }
6026 return (ret);
6027}
6028
6029/**
6030 * xmlGetMinOccurs:
6031 * @ctxt: a schema validation context
6032 * @node: a subtree containing XML Schema information
6033 *
6034 * Get the minOccurs property
6035 *
6036 * Returns the default if not found, or the value
6037 */
6038static int
6039xmlGetMinOccurs(xmlSchemaParserCtxtPtr ctxt, xmlNodePtr node,
6040 int min, int max, int def, const char *expected)
6041{
6042 const xmlChar *val, *cur;
6043 int ret = 0;
6044 xmlAttrPtr attr;
6045
6046 attr = xmlSchemaGetPropNode(node, "minOccurs");
6047 if (attr == NULL((void*)0))
6048 return (def);
6049 val = xmlSchemaGetNodeContent(ctxt, (xmlNodePtr) attr);
6050 if (val == NULL((void*)0))
6051 return (def);
6052 cur = val;
6053 while (IS_BLANK_CH(*cur)(((*cur) == 0x20) || ((0x9 <= (*cur)) && ((*cur) <=
0xa)) || ((*cur) == 0xd))
)
6054 cur++;
6055 if (*cur == 0) {
6056 xmlSchemaPSimpleTypeErr(ctxt,
6057 XML_SCHEMAP_S4S_ATTR_INVALID_VALUE,
6058 /* XML_SCHEMAP_INVALID_MINOCCURS, */
6059 NULL((void*)0), (xmlNodePtr) attr, NULL((void*)0), expected,
6060 val, NULL((void*)0), NULL((void*)0), NULL((void*)0));
6061 return (def);
6062 }
6063 while ((*cur >= '0') && (*cur <= '9')) {
6064 if (ret > INT_MAX2147483647 / 10) {
6065 ret = INT_MAX2147483647;
6066 } else {
6067 int digit = *cur - '0';
6068 ret *= 10;
6069 if (ret > INT_MAX2147483647 - digit)
6070 ret = INT_MAX2147483647;
6071 else
6072 ret += digit;
6073 }
6074 cur++;
6075 }
6076 while (IS_BLANK_CH(*cur)(((*cur) == 0x20) || ((0x9 <= (*cur)) && ((*cur) <=
0xa)) || ((*cur) == 0xd))
)
6077 cur++;
6078 /*
6079 * TODO: Restrict the maximal value to Integer.
6080 */
6081 if ((*cur != 0) || (ret < min) || ((max != -1) && (ret > max))) {
6082 xmlSchemaPSimpleTypeErr(ctxt,
6083 XML_SCHEMAP_S4S_ATTR_INVALID_VALUE,
6084 /* XML_SCHEMAP_INVALID_MINOCCURS, */
6085 NULL((void*)0), (xmlNodePtr) attr, NULL((void*)0), expected,
6086 val, NULL((void*)0), NULL((void*)0), NULL((void*)0));
6087 return (def);
6088 }
6089 return (ret);
6090}
6091
6092/**
6093 * xmlSchemaPGetBoolNodeValue:
6094 * @ctxt: a schema validation context
6095 * @ownerItem: the owner as a schema item
6096 * @node: the node holding the value
6097 *
6098 * Converts a boolean string value into 1 or 0.
6099 *
6100 * Returns 0 or 1.
6101 */
6102static int
6103xmlSchemaPGetBoolNodeValue(xmlSchemaParserCtxtPtr ctxt,
6104 xmlSchemaBasicItemPtr ownerItem,
6105 xmlNodePtr node)
6106{
6107 xmlChar *value = NULL((void*)0);
6108 int res = 0;
6109
6110 value = xmlNodeGetContent(node);
6111 /*
6112 * 3.2.2.1 Lexical representation
6113 * An instance of a datatype that is defined as `boolean`
6114 * can have the following legal literals {true, false, 1, 0}.
6115 */
6116 if (xmlStrEqual(BAD_CAST(xmlChar *) value, BAD_CAST(xmlChar *) "true"))
6117 res = 1;
6118 else if (xmlStrEqual(BAD_CAST(xmlChar *) value, BAD_CAST(xmlChar *) "false"))
6119 res = 0;
6120 else if (xmlStrEqual(BAD_CAST(xmlChar *) value, BAD_CAST(xmlChar *) "1"))
6121 res = 1;
6122 else if (xmlStrEqual(BAD_CAST(xmlChar *) value, BAD_CAST(xmlChar *) "0"))
6123 res = 0;
6124 else {
6125 xmlSchemaPSimpleTypeErr(ctxt,
6126 XML_SCHEMAP_INVALID_BOOLEAN,
6127 ownerItem, node,
6128 xmlSchemaGetBuiltInType(XML_SCHEMAS_BOOLEAN),
6129 NULL((void*)0), BAD_CAST(xmlChar *) value,
6130 NULL((void*)0), NULL((void*)0), NULL((void*)0));
6131 }
6132 if (value != NULL((void*)0))
6133 xmlFree(value);
6134 return (res);
6135}
6136
6137/**
6138 * xmlGetBooleanProp:
6139 * @ctxt: a schema validation context
6140 * @node: a subtree containing XML Schema information
6141 * @name: the attribute name
6142 * @def: the default value
6143 *
6144 * Evaluate if a boolean property is set
6145 *
6146 * Returns the default if not found, 0 if found to be false,
6147 * 1 if found to be true
6148 */
6149static int
6150xmlGetBooleanProp(xmlSchemaParserCtxtPtr ctxt,
6151 xmlNodePtr node,
6152 const char *name, int def)
6153{
6154 const xmlChar *val;
6155
6156 val = xmlSchemaGetProp(ctxt, node, name);
6157 if (val == NULL((void*)0))
6158 return (def);
6159 /*
6160 * 3.2.2.1 Lexical representation
6161 * An instance of a datatype that is defined as `boolean`
6162 * can have the following legal literals {true, false, 1, 0}.
6163 */
6164 if (xmlStrEqual(val, BAD_CAST(xmlChar *) "true"))
6165 def = 1;
6166 else if (xmlStrEqual(val, BAD_CAST(xmlChar *) "false"))
6167 def = 0;
6168 else if (xmlStrEqual(val, BAD_CAST(xmlChar *) "1"))
6169 def = 1;
6170 else if (xmlStrEqual(val, BAD_CAST(xmlChar *) "0"))
6171 def = 0;
6172 else {
6173 xmlSchemaPSimpleTypeErr(ctxt,
6174 XML_SCHEMAP_INVALID_BOOLEAN,
6175 NULL((void*)0),
6176 (xmlNodePtr) xmlSchemaGetPropNode(node, name),
6177 xmlSchemaGetBuiltInType(XML_SCHEMAS_BOOLEAN),
6178 NULL((void*)0), val, NULL((void*)0), NULL((void*)0), NULL((void*)0));
6179 }
6180 return (def);
6181}
6182
6183/************************************************************************
6184 * *
6185 * Schema extraction from an Infoset *
6186 * *
6187 ************************************************************************/
6188static xmlSchemaTypePtr xmlSchemaParseSimpleType(xmlSchemaParserCtxtPtr
6189 ctxt, xmlSchemaPtr schema,
6190 xmlNodePtr node,
6191 int topLevel);
6192static xmlSchemaTypePtr xmlSchemaParseComplexType(xmlSchemaParserCtxtPtr
6193 ctxt,
6194 xmlSchemaPtr schema,
6195 xmlNodePtr node,
6196 int topLevel);
6197static xmlSchemaTypePtr xmlSchemaParseRestriction(xmlSchemaParserCtxtPtr
6198 ctxt,
6199 xmlSchemaPtr schema,
6200 xmlNodePtr node,
6201 xmlSchemaTypeType parentType);
6202static xmlSchemaBasicItemPtr
6203xmlSchemaParseLocalAttribute(xmlSchemaParserCtxtPtr pctxt,
6204 xmlSchemaPtr schema,
6205 xmlNodePtr node,
6206 xmlSchemaItemListPtr uses,
6207 int parentType);
6208static xmlSchemaTypePtr xmlSchemaParseList(xmlSchemaParserCtxtPtr ctxt,
6209 xmlSchemaPtr schema,
6210 xmlNodePtr node);
6211static xmlSchemaWildcardPtr
6212xmlSchemaParseAnyAttribute(xmlSchemaParserCtxtPtr ctxt,
6213 xmlSchemaPtr schema, xmlNodePtr node);
6214
6215/**
6216 * xmlSchemaPValAttrNodeValue:
6217 *
6218 * @pctxt: a schema parser context
6219 * @ownerItem: the schema object owner if existent
6220 * @attr: the schema attribute node being validated
6221 * @value: the value
6222 * @type: the built-in type to be validated against
6223 *
6224 * Validates a value against the given built-in type.
6225 * This one is intended to be used internally for validation
6226 * of schema attribute values during parsing of the schema.
6227 *
6228 * Returns 0 if the value is valid, a positive error code
6229 * number otherwise and -1 in case of an internal or API error.
6230 */
6231static int
6232xmlSchemaPValAttrNodeValue(xmlSchemaParserCtxtPtr pctxt,
6233 xmlSchemaBasicItemPtr ownerItem,
6234 xmlAttrPtr attr,
6235 const xmlChar *value,
6236 xmlSchemaTypePtr type)
6237{
6238
6239 int ret = 0;
6240
6241 /*
6242 * NOTE: Should we move this to xmlschematypes.c? Hmm, but this
6243 * one is really meant to be used internally, so better not.
6244 */
6245 if ((pctxt == NULL((void*)0)) || (type == NULL((void*)0)) || (attr == NULL((void*)0)))
6246 return (-1);
6247 if (type->type != XML_SCHEMA_TYPE_BASIC) {
6248 PERROR_INT("xmlSchemaPValAttrNodeValue",xmlSchemaInternalErr((xmlSchemaAbstractCtxtPtr) pctxt, "xmlSchemaPValAttrNodeValue"
, "the given type is not a built-in type");
6249 "the given type is not a built-in type")xmlSchemaInternalErr((xmlSchemaAbstractCtxtPtr) pctxt, "xmlSchemaPValAttrNodeValue"
, "the given type is not a built-in type");
;
6250 return (-1);
6251 }
6252 switch (type->builtInType) {
6253 case XML_SCHEMAS_NCNAME:
6254 case XML_SCHEMAS_QNAME:
6255 case XML_SCHEMAS_ANYURI:
6256 case XML_SCHEMAS_TOKEN:
6257 case XML_SCHEMAS_LANGUAGE:
6258 ret = xmlSchemaValPredefTypeNode(type, value, NULL((void*)0),
6259 (xmlNodePtr) attr);
6260 break;
6261 default: {
6262 PERROR_INT("xmlSchemaPValAttrNodeValue",xmlSchemaInternalErr((xmlSchemaAbstractCtxtPtr) pctxt, "xmlSchemaPValAttrNodeValue"
, "validation using the given type is not supported while " "parsing a schema"
);
6263 "validation using the given type is not supported while "xmlSchemaInternalErr((xmlSchemaAbstractCtxtPtr) pctxt, "xmlSchemaPValAttrNodeValue"
, "validation using the given type is not supported while " "parsing a schema"
);
6264 "parsing a schema")xmlSchemaInternalErr((xmlSchemaAbstractCtxtPtr) pctxt, "xmlSchemaPValAttrNodeValue"
, "validation using the given type is not supported while " "parsing a schema"
);
;
6265 return (-1);
6266 }
6267 }
6268 /*
6269 * TODO: Should we use the S4S error codes instead?
6270 */
6271 if (ret < 0) {
6272 PERROR_INT("xmlSchemaPValAttrNodeValue",xmlSchemaInternalErr((xmlSchemaAbstractCtxtPtr) pctxt, "xmlSchemaPValAttrNodeValue"
, "failed to validate a schema attribute value");
6273 "failed to validate a schema attribute value")xmlSchemaInternalErr((xmlSchemaAbstractCtxtPtr) pctxt, "xmlSchemaPValAttrNodeValue"
, "failed to validate a schema attribute value");
;
6274 return (-1);
6275 } else if (ret > 0) {
6276 if (WXS_IS_LIST(type)(type->flags & 1 << 6))
6277 ret = XML_SCHEMAV_CVC_DATATYPE_VALID_1_2_2;
6278 else
6279 ret = XML_SCHEMAV_CVC_DATATYPE_VALID_1_2_1;
6280 xmlSchemaPSimpleTypeErr(pctxt,
6281 ret, ownerItem, (xmlNodePtr) attr,
6282 type, NULL((void*)0), value, NULL((void*)0), NULL((void*)0), NULL((void*)0));
6283 }
6284 return (ret);
6285}
6286
6287/**
6288 * xmlSchemaPValAttrNode:
6289 *
6290 * @ctxt: a schema parser context
6291 * @ownerItem: the schema object owner if existent
6292 * @attr: the schema attribute node being validated
6293 * @type: the built-in type to be validated against
6294 * @value: the resulting value if any
6295 *
6296 * Extracts and validates a value against the given built-in type.
6297 * This one is intended to be used internally for validation
6298 * of schema attribute values during parsing of the schema.
6299 *
6300 * Returns 0 if the value is valid, a positive error code
6301 * number otherwise and -1 in case of an internal or API error.
6302 */
6303static int
6304xmlSchemaPValAttrNode(xmlSchemaParserCtxtPtr ctxt,
6305 xmlSchemaBasicItemPtr ownerItem,
6306 xmlAttrPtr attr,
6307 xmlSchemaTypePtr type,
6308 const xmlChar **value)
6309{
6310 const xmlChar *val;
6311
6312 if ((ctxt == NULL((void*)0)) || (type == NULL((void*)0)) || (attr == NULL((void*)0)))
6313 return (-1);
6314
6315 val = xmlSchemaGetNodeContent(ctxt, (xmlNodePtr) attr);
6316 if (value != NULL((void*)0))
6317 *value = val;
6318
6319 return (xmlSchemaPValAttrNodeValue(ctxt, ownerItem, attr,
6320 val, type));
6321}
6322
6323/**
6324 * xmlSchemaPValAttr:
6325 *
6326 * @ctxt: a schema parser context
6327 * @node: the element node of the attribute
6328 * @ownerItem: the schema object owner if existent
6329 * @ownerElem: the owner element node
6330 * @name: the name of the schema attribute node
6331 * @type: the built-in type to be validated against
6332 * @value: the resulting value if any
6333 *
6334 * Extracts and validates a value against the given built-in type.
6335 * This one is intended to be used internally for validation
6336 * of schema attribute values during parsing of the schema.
6337 *
6338 * Returns 0 if the value is valid, a positive error code
6339 * number otherwise and -1 in case of an internal or API error.
6340 */
6341static int
6342xmlSchemaPValAttr(xmlSchemaParserCtxtPtr ctxt,
6343 xmlSchemaBasicItemPtr ownerItem,
6344 xmlNodePtr ownerElem,
6345 const char *name,
6346 xmlSchemaTypePtr type,
6347 const xmlChar **value)
6348{
6349 xmlAttrPtr attr;
6350
6351 if ((ctxt == NULL((void*)0)) || (type == NULL((void*)0))) {
6352 if (value != NULL((void*)0))
6353 *value = NULL((void*)0);
6354 return (-1);
6355 }
6356 if (type->type != XML_SCHEMA_TYPE_BASIC) {
6357 if (value != NULL((void*)0))
6358 *value = NULL((void*)0);
6359 xmlSchemaPErr(ctxt, ownerElem,
6360 XML_SCHEMAP_INTERNAL,
6361 "Internal error: xmlSchemaPValAttr, the given "
6362 "type '%s' is not a built-in type.\n",
6363 type->name, NULL((void*)0));
6364 return (-1);
6365 }
6366 attr = xmlSchemaGetPropNode(ownerElem, name);
6367 if (attr == NULL((void*)0)) {
6368 if (value != NULL((void*)0))
6369 *value = NULL((void*)0);
6370 return (0);
6371 }
6372 return (xmlSchemaPValAttrNode(ctxt, ownerItem, attr,
6373 type, value));
6374}
6375
6376static int
6377xmlSchemaCheckReference(xmlSchemaParserCtxtPtr pctxt,
6378 xmlSchemaPtr schema ATTRIBUTE_UNUSED__attribute__((unused)),
6379 xmlNodePtr node,
6380 xmlAttrPtr attr,
6381 const xmlChar *namespaceName)
6382{
6383 /* TODO: Pointer comparison instead? */
6384 if (xmlStrEqual(pctxt->targetNamespace, namespaceName))
6385 return (0);
6386 if (xmlStrEqual(xmlSchemaNs, namespaceName))
6387 return (0);
6388 /*
6389 * Check if the referenced namespace was <import>ed.
6390 */
6391 if (WXS_BUCKET(pctxt)((pctxt))->constructor->bucket->relations != NULL((void*)0)) {
6392 xmlSchemaSchemaRelationPtr rel;
6393
6394 rel = WXS_BUCKET(pctxt)((pctxt))->constructor->bucket->relations;
6395 do {
6396 if (WXS_IS_BUCKET_IMPMAIN(rel->type)(((rel->type) == 0) || ((rel->type) == 1)) &&
6397 xmlStrEqual(namespaceName, rel->importNamespace))
6398 return (0);
6399 rel = rel->next;
6400 } while (rel != NULL((void*)0));
6401 }
6402 /*
6403 * No matching <import>ed namespace found.
6404 */
6405 {
6406 xmlNodePtr n = (attr != NULL((void*)0)) ? (xmlNodePtr) attr : node;
6407
6408 if (namespaceName == NULL((void*)0))
6409 xmlSchemaCustomErr(ACTXT_CAST(xmlSchemaAbstractCtxtPtr) pctxt,
6410 XML_SCHEMAP_SRC_RESOLVE, n, NULL((void*)0),
6411 "References from this schema to components in no "
6412 "namespace are not allowed, since not indicated by an "
6413 "import statement", NULL((void*)0), NULL((void*)0));
6414 else
6415 xmlSchemaCustomErr(ACTXT_CAST(xmlSchemaAbstractCtxtPtr) pctxt,
6416 XML_SCHEMAP_SRC_RESOLVE, n, NULL((void*)0),
6417 "References from this schema to components in the "
6418 "namespace '%s' are not allowed, since not indicated by an "
6419 "import statement", namespaceName, NULL((void*)0));
6420 }
6421 return (XML_SCHEMAP_SRC_RESOLVE);
6422}
6423
6424/**
6425 * xmlSchemaParseLocalAttributes:
6426 * @ctxt: a schema validation context
6427 * @schema: the schema being built
6428 * @node: a subtree containing XML Schema information
6429 * @type: the hosting type where the attributes will be anchored
6430 *
6431 * Parses attribute uses and attribute declarations and
6432 * attribute group references.
6433 */
6434static int
6435xmlSchemaParseLocalAttributes(xmlSchemaParserCtxtPtr ctxt, xmlSchemaPtr schema,
6436 xmlNodePtr *child, xmlSchemaItemListPtr *list,
6437 int parentType, int *hasRefs)
6438{
6439 void *item;
6440
6441 while ((IS_SCHEMA((*child), "attribute")(((*child) != ((void*)0)) && ((*child)->ns != ((void
*)0)) && (xmlStrEqual((*child)->name, (const xmlChar
*) "attribute")) && (xmlStrEqual((*child)->ns->
href, xmlSchemaNs)))
) ||
6442 (IS_SCHEMA((*child), "attributeGroup")(((*child) != ((void*)0)) && ((*child)->ns != ((void
*)0)) && (xmlStrEqual((*child)->name, (const xmlChar
*) "attributeGroup")) && (xmlStrEqual((*child)->ns
->href, xmlSchemaNs)))
)) {
6443 if (IS_SCHEMA((*child), "attribute")(((*child) != ((void*)0)) && ((*child)->ns != ((void
*)0)) && (xmlStrEqual((*child)->name, (const xmlChar
*) "attribute")) && (xmlStrEqual((*child)->ns->
href, xmlSchemaNs)))
) {
6444 item = xmlSchemaParseLocalAttribute(ctxt, schema, *child,
6445 *list, parentType);
6446 } else {
6447 item = xmlSchemaParseAttributeGroupRef(ctxt, schema, *child);
6448 if ((item != NULL((void*)0)) && (hasRefs != NULL((void*)0)))
6449 *hasRefs = 1;
6450 }
6451 if (item != NULL((void*)0)) {
6452 if (*list == NULL((void*)0)) {
6453 /* TODO: Customize grow factor. */
6454 *list = xmlSchemaItemListCreate();
6455 if (*list == NULL((void*)0))
6456 return(-1);
6457 }
6458 if (xmlSchemaItemListAddSize(*list, 2, item) == -1)
6459 return(-1);
6460 }
6461 *child = (*child)->next;
6462 }
6463 return (0);
6464}
6465
6466/**
6467 * xmlSchemaParseAnnotation:
6468 * @ctxt: a schema validation context
6469 * @schema: the schema being built
6470 * @node: a subtree containing XML Schema information
6471 *
6472 * parse a XML schema Attribute declaration
6473 * *WARNING* this interface is highly subject to change
6474 *
6475 * Returns -1 in case of error, 0 if the declaration is improper and
6476 * 1 in case of success.
6477 */
6478static xmlSchemaAnnotPtr
6479xmlSchemaParseAnnotation(xmlSchemaParserCtxtPtr ctxt, xmlNodePtr node, int needed)
6480{
6481 xmlSchemaAnnotPtr ret;
6482 xmlNodePtr child = NULL((void*)0);
6483 xmlAttrPtr attr;
6484 int barked = 0;
6485
6486 /*
6487 * INFO: S4S completed.
6488 */
6489 /*
6490 * id = ID
6491 * {any attributes with non-schema namespace . . .}>
6492 * Content: (appinfo | documentation)*
6493 */
6494 if ((ctxt == NULL((void*)0)) || (node == NULL((void*)0)))
6495 return (NULL((void*)0));
6496 if (needed)
6497 ret = xmlSchemaNewAnnot(ctxt, node);
6498 else
6499 ret = NULL((void*)0);
6500 attr = node->properties;
6501 while (attr != NULL((void*)0)) {
6502 if (((attr->ns == NULL((void*)0)) &&
6503 (!xmlStrEqual(attr->name, BAD_CAST(xmlChar *) "id"))) ||
6504 ((attr->ns != NULL((void*)0)) &&
6505 xmlStrEqual(attr->ns->href, xmlSchemaNs))) {
6506
6507 xmlSchemaPIllegalAttrErr(ctxt,
6508 XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL((void*)0), attr);
6509 }
6510 attr = attr->next;
6511 }
6512 xmlSchemaPValAttrID(ctxt, node, BAD_CAST(xmlChar *) "id");
6513 /*
6514 * And now for the children...
6515 */
6516 child = node->children;
6517 while (child != NULL((void*)0)) {
6518 if (IS_SCHEMA(child, "appinfo")((child != ((void*)0)) && (child->ns != ((void*)0)
) && (xmlStrEqual(child->name, (const xmlChar *) "appinfo"
)) && (xmlStrEqual(child->ns->href, xmlSchemaNs
)))
) {
6519 /* TODO: make available the content of "appinfo". */
6520 /*
6521 * source = anyURI
6522 * {any attributes with non-schema namespace . . .}>
6523 * Content: ({any})*
6524 */
6525 attr = child->properties;
6526 while (attr != NULL((void*)0)) {
6527 if (((attr->ns == NULL((void*)0)) &&
6528 (!xmlStrEqual(attr->name, BAD_CAST(xmlChar *) "source"))) ||
6529 ((attr->ns != NULL((void*)0)) &&
6530 xmlStrEqual(attr->ns->href, xmlSchemaNs))) {
6531
6532 xmlSchemaPIllegalAttrErr(ctxt,
6533 XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL((void*)0), attr);
6534 }
6535 attr = attr->next;
6536 }
6537 xmlSchemaPValAttr(ctxt, NULL((void*)0), child, "source",
6538 xmlSchemaGetBuiltInType(XML_SCHEMAS_ANYURI), NULL((void*)0));
6539 child = child->next;
6540 } else if (IS_SCHEMA(child, "documentation")((child != ((void*)0)) && (child->ns != ((void*)0)
) && (xmlStrEqual(child->name, (const xmlChar *) "documentation"
)) && (xmlStrEqual(child->ns->href, xmlSchemaNs
)))
) {
6541 /* TODO: make available the content of "documentation". */
6542 /*
6543 * source = anyURI
6544 * {any attributes with non-schema namespace . . .}>
6545 * Content: ({any})*
6546 */
6547 attr = child->properties;
6548 while (attr != NULL((void*)0)) {
6549 if (attr->ns == NULL((void*)0)) {
6550 if (!xmlStrEqual(attr->name, BAD_CAST(xmlChar *) "source")) {
6551 xmlSchemaPIllegalAttrErr(ctxt,
6552 XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL((void*)0), attr);
6553 }
6554 } else {
6555 if (xmlStrEqual(attr->ns->href, xmlSchemaNs) ||
6556 (xmlStrEqual(attr->name, BAD_CAST(xmlChar *) "lang") &&
6557 (!xmlStrEqual(attr->ns->href, XML_XML_NAMESPACE(const xmlChar *) "http://www.w3.org/XML/1998/namespace")))) {
6558
6559 xmlSchemaPIllegalAttrErr(ctxt,
6560 XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL((void*)0), attr);
6561 }
6562 }
6563 attr = attr->next;
6564 }
6565 /*
6566 * Attribute "xml:lang".
6567 */
6568 attr = xmlSchemaGetPropNodeNs(child, (const char *) XML_XML_NAMESPACE(const xmlChar *) "http://www.w3.org/XML/1998/namespace", "lang");
6569 if (attr != NULL((void*)0))
6570 xmlSchemaPValAttrNode(ctxt, NULL((void*)0), attr,
6571 xmlSchemaGetBuiltInType(XML_SCHEMAS_LANGUAGE), NULL((void*)0));
6572 child = child->next;
6573 } else {
6574 if (!barked)
6575 xmlSchemaPContentErr(ctxt,
6576 XML_SCHEMAP_S4S_ELEM_NOT_ALLOWED,
6577 NULL((void*)0), node, child, NULL((void*)0), "(appinfo | documentation)*");
6578 barked = 1;
6579 child = child->next;
6580 }
6581 }
6582
6583 return (ret);
6584}
6585
6586/**
6587 * xmlSchemaParseFacet:
6588 * @ctxt: a schema validation context
6589 * @schema: the schema being built
6590 * @node: a subtree containing XML Schema information
6591 *
6592 * parse a XML schema Facet declaration
6593 * *WARNING* this interface is highly subject to change
6594 *
6595 * Returns the new type structure or NULL in case of error
6596 */
6597static xmlSchemaFacetPtr
6598xmlSchemaParseFacet(xmlSchemaParserCtxtPtr ctxt, xmlSchemaPtr schema,
6599 xmlNodePtr node)
6600{
6601 xmlSchemaFacetPtr facet;
6602 xmlNodePtr child = NULL((void*)0);
6603 const xmlChar *value;
6604
6605 if ((ctxt == NULL((void*)0)) || (schema == NULL((void*)0)) || (node == NULL((void*)0)))
6606 return (NULL((void*)0));
6607
6608 facet = xmlSchemaNewFacet();
6609 if (facet == NULL((void*)0)) {
6610 xmlSchemaPErrMemory(ctxt, "allocating facet", node);
6611 return (NULL((void*)0));
6612 }
6613 facet->node = node;
6614 value = xmlSchemaGetProp(ctxt, node, "value");
6615 if (value == NULL((void*)0)) {
6616 xmlSchemaPErr2(ctxt, node, child, XML_SCHEMAP_FACET_NO_VALUE,
6617 "Facet %s has no value\n", node->name, NULL((void*)0));
6618 xmlSchemaFreeFacet(facet);
6619 return (NULL((void*)0));
6620 }
6621 if (IS_SCHEMA(node, "minInclusive")((node != ((void*)0)) && (node->ns != ((void*)0)) &&
(xmlStrEqual(node->name, (const xmlChar *) "minInclusive"
)) && (xmlStrEqual(node->ns->href, xmlSchemaNs)
))
) {
6622 facet->type = XML_SCHEMA_FACET_MININCLUSIVE;
6623 } else if (IS_SCHEMA(node, "minExclusive")((node != ((void*)0)) && (node->ns != ((void*)0)) &&
(xmlStrEqual(node->name, (const xmlChar *) "minExclusive"
)) && (xmlStrEqual(node->ns->href, xmlSchemaNs)
))
) {
6624 facet->type = XML_SCHEMA_FACET_MINEXCLUSIVE;
6625 } else if (IS_SCHEMA(node, "maxInclusive")((node != ((void*)0)) && (node->ns != ((void*)0)) &&
(xmlStrEqual(node->name, (const xmlChar *) "maxInclusive"
)) && (xmlStrEqual(node->ns->href, xmlSchemaNs)
))
) {
6626 facet->type = XML_SCHEMA_FACET_MAXINCLUSIVE;
6627 } else if (IS_SCHEMA(node, "maxExclusive")((node != ((void*)0)) && (node->ns != ((void*)0)) &&
(xmlStrEqual(node->name, (const xmlChar *) "maxExclusive"
)) && (xmlStrEqual(node->ns->href, xmlSchemaNs)
))
) {
6628 facet->type = XML_SCHEMA_FACET_MAXEXCLUSIVE;
6629 } else if (IS_SCHEMA(node, "totalDigits")((node != ((void*)0)) && (node->ns != ((void*)0)) &&
(xmlStrEqual(node->name, (const xmlChar *) "totalDigits")
) && (xmlStrEqual(node->ns->href, xmlSchemaNs))
)
) {
6630 facet->type = XML_SCHEMA_FACET_TOTALDIGITS;
6631 } else if (IS_SCHEMA(node, "fractionDigits")((node != ((void*)0)) && (node->ns != ((void*)0)) &&
(xmlStrEqual(node->name, (const xmlChar *) "fractionDigits"
)) && (xmlStrEqual(node->ns->href, xmlSchemaNs)
))
) {
6632 facet->type = XML_SCHEMA_FACET_FRACTIONDIGITS;
6633 } else if (IS_SCHEMA(node, "pattern")((node != ((void*)0)) && (node->ns != ((void*)0)) &&
(xmlStrEqual(node->name, (const xmlChar *) "pattern")) &&
(xmlStrEqual(node->ns->href, xmlSchemaNs)))
) {
6634 facet->type = XML_SCHEMA_FACET_PATTERN;
6635 } else if (IS_SCHEMA(node, "enumeration")((node != ((void*)0)) && (node->ns != ((void*)0)) &&
(xmlStrEqual(node->name, (const xmlChar *) "enumeration")
) && (xmlStrEqual(node->ns->href, xmlSchemaNs))
)
) {
6636 facet->type = XML_SCHEMA_FACET_ENUMERATION;
6637 } else if (IS_SCHEMA(node, "whiteSpace")((node != ((void*)0)) && (node->ns != ((void*)0)) &&
(xmlStrEqual(node->name, (const xmlChar *) "whiteSpace"))
&& (xmlStrEqual(node->ns->href, xmlSchemaNs)))
) {
6638 facet->type = XML_SCHEMA_FACET_WHITESPACE;
6639 } else if (IS_SCHEMA(node, "length")((node != ((void*)0)) && (node->ns != ((void*)0)) &&
(xmlStrEqual(node->name, (const xmlChar *) "length")) &&
(xmlStrEqual(node->ns->href, xmlSchemaNs)))
) {
6640 facet->type = XML_SCHEMA_FACET_LENGTH;
6641 } else if (IS_SCHEMA(node, "maxLength")((node != ((void*)0)) && (node->ns != ((void*)0)) &&
(xmlStrEqual(node->name, (const xmlChar *) "maxLength")) &&
(xmlStrEqual(node->ns->href, xmlSchemaNs)))
) {
6642 facet->type = XML_SCHEMA_FACET_MAXLENGTH;
6643 } else if (IS_SCHEMA(node, "minLength")((node != ((void*)0)) && (node->ns != ((void*)0)) &&
(xmlStrEqual(node->name, (const xmlChar *) "minLength")) &&
(xmlStrEqual(node->ns->href, xmlSchemaNs)))
) {
6644 facet->type = XML_SCHEMA_FACET_MINLENGTH;
6645 } else {
6646 xmlSchemaPErr2(ctxt, node, child, XML_SCHEMAP_UNKNOWN_FACET_TYPE,
6647 "Unknown facet type %s\n", node->name, NULL((void*)0));
6648 xmlSchemaFreeFacet(facet);
6649 return (NULL((void*)0));
6650 }
6651 xmlSchemaPValAttrID(ctxt, node, BAD_CAST(xmlChar *) "id");
6652 facet->value = value;
6653 if ((facet->type != XML_SCHEMA_FACET_PATTERN) &&
6654 (facet->type != XML_SCHEMA_FACET_ENUMERATION)) {
6655 const xmlChar *fixed;
6656
6657 fixed = xmlSchemaGetProp(ctxt, node, "fixed");
6658 if (fixed != NULL((void*)0)) {
6659 if (xmlStrEqual(fixed, BAD_CAST(xmlChar *) "true"))
6660 facet->fixed = 1;
6661 }
6662 }
6663 child = node->children;
6664
6665 if (IS_SCHEMA(child, "annotation")((child != ((void*)0)) && (child->ns != ((void*)0)
) && (xmlStrEqual(child->name, (const xmlChar *) "annotation"
)) && (xmlStrEqual(child->ns->href, xmlSchemaNs
)))
) {
6666 facet->annot = xmlSchemaParseAnnotation(ctxt, child, 1);
6667 child = child->next;
6668 }
6669 if (child != NULL((void*)0)) {
6670 xmlSchemaPErr2(ctxt, node, child, XML_SCHEMAP_UNKNOWN_FACET_CHILD,
6671 "Facet %s has unexpected child content\n",
6672 node->name, NULL((void*)0));
6673 }
6674 return (facet);
6675}
6676
6677/**
6678 * xmlSchemaParseWildcardNs:
6679 * @ctxt: a schema parser context
6680 * @wildc: the wildcard, already created
6681 * @node: a subtree containing XML Schema information
6682 *
6683 * Parses the attribute "processContents" and "namespace"
6684 * of a xsd:anyAttribute and xsd:any.
6685 * *WARNING* this interface is highly subject to change
6686 *
6687 * Returns 0 if everything goes fine, a positive error code
6688 * if something is not valid and -1 if an internal error occurs.
6689 */
6690static int
6691xmlSchemaParseWildcardNs(xmlSchemaParserCtxtPtr ctxt,
6692 xmlSchemaPtr schema ATTRIBUTE_UNUSED__attribute__((unused)),
6693 xmlSchemaWildcardPtr wildc,
6694 xmlNodePtr node)
6695{
6696 const xmlChar *pc, *ns, *dictnsItem;
6697 int ret = 0;
6698 xmlChar *nsItem;
6699 xmlSchemaWildcardNsPtr tmp, lastNs = NULL((void*)0);
6700 xmlAttrPtr attr;
6701
6702 pc = xmlSchemaGetProp(ctxt, node, "processContents");
6703 if ((pc == NULL((void*)0))
6704 || (xmlStrEqual(pc, (const xmlChar *) "strict"))) {
6705 wildc->processContents = XML_SCHEMAS_ANY_STRICT3;
6706 } else if (xmlStrEqual(pc, (const xmlChar *) "skip")) {
6707 wildc->processContents = XML_SCHEMAS_ANY_SKIP1;
6708 } else if (xmlStrEqual(pc, (const xmlChar *) "lax")) {
6709 wildc->processContents = XML_SCHEMAS_ANY_LAX2;
6710 } else {
6711 xmlSchemaPSimpleTypeErr(ctxt,
6712 XML_SCHEMAP_S4S_ATTR_INVALID_VALUE,
6713 NULL((void*)0), node,
6714 NULL((void*)0), "(strict | skip | lax)", pc,
6715 NULL((void*)0), NULL((void*)0), NULL((void*)0));
6716 wildc->processContents = XML_SCHEMAS_ANY_STRICT3;
6717 ret = XML_SCHEMAP_S4S_ATTR_INVALID_VALUE;
6718 }
6719 /*
6720 * Build the namespace constraints.
6721 */
6722 attr = xmlSchemaGetPropNode(node, "namespace");
6723 ns = xmlSchemaGetNodeContent(ctxt, (xmlNodePtr) attr);
6724 if (ns == NULL((void*)0))
6725 return (-1);
6726 if ((attr == NULL((void*)0)) || (xmlStrEqual(ns, BAD_CAST(xmlChar *) "##any")))
6727 wildc->any = 1;
6728 else if (xmlStrEqual(ns, BAD_CAST(xmlChar *) "##other")) {
6729 wildc->negNsSet = xmlSchemaNewWildcardNsConstraint(ctxt);
6730 if (wildc->negNsSet == NULL((void*)0)) {
6731 return (-1);
6732 }
6733 wildc->negNsSet->value = ctxt->targetNamespace;
6734 } else {
6735 const xmlChar *end, *cur;
6736
6737 cur = ns;
6738 do {
6739 while (IS_BLANK_CH(*cur)(((*cur) == 0x20) || ((0x9 <= (*cur)) && ((*cur) <=
0xa)) || ((*cur) == 0xd))
)
6740 cur++;
6741 end = cur;
6742 while ((*end != 0) && (!(IS_BLANK_CH(*end)(((*end) == 0x20) || ((0x9 <= (*end)) && ((*end) <=
0xa)) || ((*end) == 0xd))
)))
6743 end++;
6744 if (end == cur)
6745 break;
6746 nsItem = xmlStrndup(cur, end - cur);
6747 if ((xmlStrEqual(nsItem, BAD_CAST(xmlChar *) "##other")) ||
6748 (xmlStrEqual(nsItem, BAD_CAST(xmlChar *) "##any"))) {
6749 xmlSchemaPSimpleTypeErr(ctxt,
6750 XML_SCHEMAP_WILDCARD_INVALID_NS_MEMBER,
6751 NULL((void*)0), (xmlNodePtr) attr,
6752 NULL((void*)0),
6753 "((##any | ##other) | List of (xs:anyURI | "
6754 "(##targetNamespace | ##local)))",
6755 nsItem, NULL((void*)0), NULL((void*)0), NULL((void*)0));
6756 ret = XML_SCHEMAP_WILDCARD_INVALID_NS_MEMBER;
6757 } else {
6758 if (xmlStrEqual(nsItem, BAD_CAST(xmlChar *) "##targetNamespace")) {
6759 dictnsItem = ctxt->targetNamespace;
6760 } else if (xmlStrEqual(nsItem, BAD_CAST(xmlChar *) "##local")) {
6761 dictnsItem = NULL((void*)0);
6762 } else {
6763 /*
6764 * Validate the item (anyURI).
6765 */
6766 xmlSchemaPValAttrNodeValue(ctxt, NULL((void*)0), attr,
6767 nsItem, xmlSchemaGetBuiltInType(XML_SCHEMAS_ANYURI));
6768 dictnsItem = xmlDictLookup(ctxt->dict, nsItem, -1);
6769 }
6770 /*
6771 * Avoid duplicate namespaces.
6772 */
6773 tmp = wildc->nsSet;
6774 while (tmp != NULL((void*)0)) {
6775 if (dictnsItem == tmp->value)
6776 break;
6777 tmp = tmp->next;
6778 }
6779 if (tmp == NULL((void*)0)) {
6780 tmp = xmlSchemaNewWildcardNsConstraint(ctxt);
6781 if (tmp == NULL((void*)0)) {
6782 xmlFree(nsItem);
6783 return (-1);
6784 }
6785 tmp->value = dictnsItem;
6786 tmp->next = NULL((void*)0);
6787 if (wildc->nsSet == NULL((void*)0))
6788 wildc->nsSet = tmp;
6789 else if (lastNs != NULL((void*)0))
6790 lastNs->next = tmp;
6791 lastNs = tmp;
6792 }
6793
6794 }
6795 xmlFree(nsItem);
6796 cur = end;
6797 } while (*cur != 0);
6798 }
6799 return (ret);
6800}
6801
6802static int
6803xmlSchemaPCheckParticleCorrect_2(xmlSchemaParserCtxtPtr ctxt,
6804 xmlSchemaParticlePtr item ATTRIBUTE_UNUSED__attribute__((unused)),
6805 xmlNodePtr node,
6806 int minOccurs,
6807 int maxOccurs) {
6808
6809 if ((maxOccurs == 0) && ( minOccurs == 0))
6810 return (0);
6811 if (maxOccurs != UNBOUNDED(1 << 30)) {
6812 /*
6813 * TODO: Maybe we should better not create the particle,
6814 * if min/max is invalid, since it could confuse the build of the
6815 * content model.
6816 */
6817 /*
6818 * 3.9.6 Schema Component Constraint: Particle Correct
6819 *
6820 */
6821 if (maxOccurs < 1) {
6822 /*
6823 * 2.2 {max occurs} must be greater than or equal to 1.
6824 */
6825 xmlSchemaPCustomAttrErr(ctxt,
6826 XML_SCHEMAP_P_PROPS_CORRECT_2_2,
6827 NULL((void*)0), NULL((void*)0),
6828 xmlSchemaGetPropNode(node, "maxOccurs"),
6829 "The value must be greater than or equal to 1");
6830 return (XML_SCHEMAP_P_PROPS_CORRECT_2_2);
6831 } else if (minOccurs > maxOccurs) {
6832 /*
6833 * 2.1 {min occurs} must not be greater than {max occurs}.
6834 */
6835 xmlSchemaPCustomAttrErr(ctxt,
6836 XML_SCHEMAP_P_PROPS_CORRECT_2_1,
6837 NULL((void*)0), NULL((void*)0),
6838 xmlSchemaGetPropNode(node, "minOccurs"),
6839 "The value must not be greater than the value of 'maxOccurs'");
6840 return (XML_SCHEMAP_P_PROPS_CORRECT_2_1);
6841 }
6842 }
6843 return (0);
6844}
6845
6846/**
6847 * xmlSchemaParseAny:
6848 * @ctxt: a schema validation context
6849 * @schema: the schema being built
6850 * @node: a subtree containing XML Schema information
6851 *
6852 * Parsea a XML schema <any> element. A particle and wildcard
6853 * will be created (except if minOccurs==maxOccurs==0, in this case
6854 * nothing will be created).
6855 * *WARNING* this interface is highly subject to change
6856 *
6857 * Returns the particle or NULL in case of error or if minOccurs==maxOccurs==0
6858 */
6859static xmlSchemaParticlePtr
6860xmlSchemaParseAny(xmlSchemaParserCtxtPtr ctxt, xmlSchemaPtr schema,
6861 xmlNodePtr node)
6862{
6863 xmlSchemaParticlePtr particle;
6864 xmlNodePtr child = NULL((void*)0);
6865 xmlSchemaWildcardPtr wild;
6866 int min, max;
6867 xmlAttrPtr attr;
6868 xmlSchemaAnnotPtr annot = NULL((void*)0);
6869
6870 if ((ctxt == NULL((void*)0)) || (schema == NULL((void*)0)) || (node == NULL((void*)0)))
6871 return (NULL((void*)0));
6872 /*
6873 * Check for illegal attributes.
6874 */
6875 attr = node->properties;
6876 while (attr != NULL((void*)0)) {
6877 if (attr->ns == NULL((void*)0)) {
6878 if ((!xmlStrEqual(attr->name, BAD_CAST(xmlChar *) "id")) &&
6879 (!xmlStrEqual(attr->name, BAD_CAST(xmlChar *) "minOccurs")) &&
6880 (!xmlStrEqual(attr->name, BAD_CAST(xmlChar *) "maxOccurs")) &&
6881 (!xmlStrEqual(attr->name, BAD_CAST(xmlChar *) "namespace")) &&
6882 (!xmlStrEqual(attr->name, BAD_CAST(xmlChar *) "processContents"))) {
6883 xmlSchemaPIllegalAttrErr(ctxt,
6884 XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL((void*)0), attr);
6885 }
6886 } else if (xmlStrEqual(attr->ns->href, xmlSchemaNs)) {
6887 xmlSchemaPIllegalAttrErr(ctxt,
6888 XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL((void*)0), attr);
6889 }
6890 attr = attr->next;
6891 }
6892 xmlSchemaPValAttrID(ctxt, node, BAD_CAST(xmlChar *) "id");
6893 /*
6894 * minOccurs/maxOccurs.
6895 */
6896 max = xmlGetMaxOccurs(ctxt, node, 0, UNBOUNDED(1 << 30), 1,
6897 "(xs:nonNegativeInteger | unbounded)");
6898 min = xmlGetMinOccurs(ctxt, node, 0, -1, 1,
6899 "xs:nonNegativeInteger");
6900 xmlSchemaPCheckParticleCorrect_2(ctxt, NULL((void*)0), node, min, max);
6901 /*
6902 * Create & parse the wildcard.
6903 */
6904 wild = xmlSchemaAddWildcard(ctxt, schema, XML_SCHEMA_TYPE_ANY, node);
6905 if (wild == NULL((void*)0))
6906 return (NULL((void*)0));
6907 xmlSchemaParseWildcardNs(ctxt, schema, wild, node);
6908 /*
6909 * And now for the children...
6910 */
6911 child = node->children;
6912 if (IS_SCHEMA(child, "annotation")((child != ((void*)0)) && (child->ns != ((void*)0)
) && (xmlStrEqual(child->name, (const xmlChar *) "annotation"
)) && (xmlStrEqual(child->ns->href, xmlSchemaNs
)))
) {
6913 annot = xmlSchemaParseAnnotation(ctxt, child, 1);
6914 child = child->next;
6915 }
6916 if (child != NULL((void*)0)) {
6917 xmlSchemaPContentErr(ctxt,
6918 XML_SCHEMAP_S4S_ELEM_NOT_ALLOWED,
6919 NULL((void*)0), node, child,
6920 NULL((void*)0), "(annotation?)");
6921 }
6922 /*
6923 * No component if minOccurs==maxOccurs==0.
6924 */
6925 if ((min == 0) && (max == 0)) {
6926 /* Don't free the wildcard, since it's already on the list. */
6927 return (NULL((void*)0));
6928 }
6929 /*
6930 * Create the particle.
6931 */
6932 particle = xmlSchemaAddParticle(ctxt, node, min, max);
6933 if (particle == NULL((void*)0))
6934 return (NULL((void*)0));
6935 particle->annot = annot;
6936 particle->children = (xmlSchemaTreeItemPtr) wild;
6937
6938 return (particle);
6939}
6940
6941/**
6942 * xmlSchemaParseNotation:
6943 * @ctxt: a schema validation context
6944 * @schema: the schema being built
6945 * @node: a subtree containing XML Schema information
6946 *
6947 * parse a XML schema Notation declaration
6948 *
6949 * Returns the new structure or NULL in case of error
6950 */
6951static xmlSchemaNotationPtr
6952xmlSchemaParseNotation(xmlSchemaParserCtxtPtr ctxt, xmlSchemaPtr schema,
6953 xmlNodePtr node)
6954{
6955 const xmlChar *name;
6956 xmlSchemaNotationPtr ret;
6957 xmlNodePtr child = NULL((void*)0);
6958
6959 if ((ctxt == NULL((void*)0)) || (schema == NULL((void*)0)) || (node == NULL((void*)0)))
6960 return (NULL((void*)0));
6961 name = xmlSchemaGetProp(ctxt, node, "name");
6962 if (name == NULL((void*)0)) {
6963 xmlSchemaPErr2(ctxt, node, child, XML_SCHEMAP_NOTATION_NO_NAME,
6964 "Notation has no name\n", NULL((void*)0), NULL((void*)0));
6965 return (NULL((void*)0));
6966 }
6967 ret = xmlSchemaAddNotation(ctxt, schema, name,
6968 ctxt->targetNamespace, node);
6969 if (ret == NULL((void*)0))
6970 return (NULL((void*)0));
6971 xmlSchemaPValAttrID(ctxt, node, BAD_CAST(xmlChar *) "id");
6972
6973 child = node->children;
6974 if (IS_SCHEMA(child, "annotation")((child != ((void*)0)) && (child->ns != ((void*)0)
) && (xmlStrEqual(child->name, (const xmlChar *) "annotation"
)) && (xmlStrEqual(child->ns->href, xmlSchemaNs
)))
) {
6975 ret->annot = xmlSchemaParseAnnotation(ctxt, child, 1);
6976 child = child->next;
6977 }
6978 if (child != NULL((void*)0)) {
6979 xmlSchemaPContentErr(ctxt,
6980 XML_SCHEMAP_S4S_ELEM_NOT_ALLOWED,
6981 NULL((void*)0), node, child,
6982 NULL((void*)0), "(annotation?)");
6983 }
6984
6985 return (ret);
6986}
6987
6988/**
6989 * xmlSchemaParseAnyAttribute:
6990 * @ctxt: a schema validation context
6991 * @schema: the schema being built
6992 * @node: a subtree containing XML Schema information
6993 *
6994 * parse a XML schema AnyAttribute declaration
6995 * *WARNING* this interface is highly subject to change
6996 *
6997 * Returns a wildcard or NULL.
6998 */
6999static xmlSchemaWildcardPtr
7000xmlSchemaParseAnyAttribute(xmlSchemaParserCtxtPtr ctxt,
7001 xmlSchemaPtr schema, xmlNodePtr node)
7002{
7003 xmlSchemaWildcardPtr ret;
7004 xmlNodePtr child = NULL((void*)0);
7005 xmlAttrPtr attr;
7006
7007 if ((ctxt == NULL((void*)0)) || (schema == NULL((void*)0)) || (node == NULL((void*)0)))
7008 return (NULL((void*)0));
7009
7010 ret = xmlSchemaAddWildcard(ctxt, schema, XML_SCHEMA_TYPE_ANY_ATTRIBUTE,
7011 node);
7012 if (ret == NULL((void*)0)) {
7013 return (NULL((void*)0));
7014 }
7015 /*
7016 * Check for illegal attributes.
7017 */
7018 attr = node->properties;
7019 while (attr != NULL((void*)0)) {
7020 if (attr->ns == NULL((void*)0)) {
7021 if ((!xmlStrEqual(attr->name, BAD_CAST(xmlChar *) "id")) &&
7022 (!xmlStrEqual(attr->name, BAD_CAST(xmlChar *) "namespace")) &&
7023 (!xmlStrEqual(attr->name, BAD_CAST(xmlChar *) "processContents"))) {
7024 xmlSchemaPIllegalAttrErr(ctxt,
7025 XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL((void*)0), attr);
7026 }
7027 } else if (xmlStrEqual(attr->ns->href, xmlSchemaNs)) {
7028 xmlSchemaPIllegalAttrErr(ctxt,
7029 XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL((void*)0), attr);
7030 }
7031 attr = attr->next;
7032 }
7033 xmlSchemaPValAttrID(ctxt, node, BAD_CAST(xmlChar *) "id");
7034 /*
7035 * Parse the namespace list.
7036 */
7037 if (xmlSchemaParseWildcardNs(ctxt, schema, ret, node) != 0)
7038 return (NULL((void*)0));
7039 /*
7040 * And now for the children...
7041 */
7042 child = node->children;
7043 if (IS_SCHEMA(child, "annotation")((child != ((void*)0)) && (child->ns != ((void*)0)
) && (xmlStrEqual(child->name, (const xmlChar *) "annotation"
)) && (xmlStrEqual(child->ns->href, xmlSchemaNs
)))
) {
7044 ret->annot = xmlSchemaParseAnnotation(ctxt, child, 1);
7045 child = child->next;
7046 }
7047 if (child != NULL((void*)0)) {
7048 xmlSchemaPContentErr(ctxt,
7049 XML_SCHEMAP_S4S_ELEM_NOT_ALLOWED,
7050 NULL((void*)0), node, child,
7051 NULL((void*)0), "(annotation?)");
7052 }
7053
7054 return (ret);
7055}
7056
7057
7058/**
7059 * xmlSchemaParseAttribute:
7060 * @ctxt: a schema validation context
7061 * @schema: the schema being built
7062 * @node: a subtree containing XML Schema information
7063 *
7064 * parse a XML schema Attribute declaration
7065 * *WARNING* this interface is highly subject to change
7066 *
7067 * Returns the attribute declaration.
7068 */
7069static xmlSchemaBasicItemPtr
7070xmlSchemaParseLocalAttribute(xmlSchemaParserCtxtPtr pctxt,
7071 xmlSchemaPtr schema,
7072 xmlNodePtr node,
7073 xmlSchemaItemListPtr uses,
7074 int parentType)
7075{
7076 const xmlChar *attrValue, *name = NULL((void*)0), *ns = NULL((void*)0);
7077 xmlSchemaAttributeUsePtr use = NULL((void*)0);
7078 xmlNodePtr child = NULL((void*)0);
7079 xmlAttrPtr attr;
7080 const xmlChar *tmpNs = NULL((void*)0), *tmpName = NULL((void*)0), *defValue = NULL((void*)0);
7081 int isRef = 0, occurs = XML_SCHEMAS_ATTR_USE_OPTIONAL2;
7082 int nberrors, hasForm = 0, defValueType = 0;
7083
7084#define WXS_ATTR_DEF_VAL_DEFAULT1 1
7085#define WXS_ATTR_DEF_VAL_FIXED2 2
7086
7087 /*
7088 * 3.2.3 Constraints on XML Representations of Attribute Declarations
7089 */
7090
7091 if ((pctxt == NULL((void*)0)) || (schema == NULL((void*)0)) || (node == NULL((void*)0)))
7092 return (NULL((void*)0));
7093 attr = xmlSchemaGetPropNode(node, "ref");
7094 if (attr != NULL((void*)0)) {
7095 if (xmlSchemaPValAttrNodeQName(pctxt, schema,
7096 NULL((void*)0), attr, &tmpNs, &tmpName) != 0) {
7097 return (NULL((void*)0));
7098 }
7099 if (xmlSchemaCheckReference(pctxt, schema, node, attr, tmpNs) != 0)
7100 return(NULL((void*)0));
7101 isRef = 1;
7102 }
7103 nberrors = pctxt->nberrors;
7104 /*
7105 * Check for illegal attributes.
7106 */
7107 attr = node->properties;
7108 while (attr != NULL((void*)0)) {
7109 if (attr->ns == NULL((void*)0)) {
7110 if (isRef) {
7111 if (xmlStrEqual(attr->name, BAD_CAST(xmlChar *) "id")) {
7112 xmlSchemaPValAttrNodeID(pctxt, attr);
7113 goto attr_next;
7114 } else if (xmlStrEqual(attr->name, BAD_CAST(xmlChar *) "ref")) {
7115 goto attr_next;
7116 }
7117 } else {
7118 if (xmlStrEqual(attr->name, BAD_CAST(xmlChar *) "name")) {
7119 goto attr_next;
7120 } else if (xmlStrEqual(attr->name, BAD_CAST(xmlChar *) "id")) {
7121 xmlSchemaPValAttrNodeID(pctxt, attr);
7122 goto attr_next;
7123 } else if (xmlStrEqual(attr->name, BAD_CAST(xmlChar *) "type")) {
7124 xmlSchemaPValAttrNodeQName(pctxt, schema, NULL((void*)0),
7125 attr, &tmpNs, &tmpName);
7126 goto attr_next;
7127 } else if (xmlStrEqual(attr->name, BAD_CAST(xmlChar *) "form")) {
7128 /*
7129 * Evaluate the target namespace
7130 */
7131 hasForm = 1;
7132 attrValue = xmlSchemaGetNodeContent(pctxt,
7133 (xmlNodePtr) attr);
7134 if (xmlStrEqual(attrValue, BAD_CAST(xmlChar *) "qualified")) {
7135 ns = pctxt->targetNamespace;
7136 } else if (!xmlStrEqual(attrValue, BAD_CAST(xmlChar *) "unqualified"))
7137 {
7138 xmlSchemaPSimpleTypeErr(pctxt,
7139 XML_SCHEMAP_S4S_ATTR_INVALID_VALUE,
7140 NULL((void*)0), (xmlNodePtr) attr,
7141 NULL((void*)0), "(qualified | unqualified)",
7142 attrValue, NULL((void*)0), NULL((void*)0), NULL((void*)0));
7143 }
7144 goto attr_next;
7145 }
7146 }
7147 if (xmlStrEqual(attr->name, BAD_CAST(xmlChar *) "use")) {
7148
7149 attrValue = xmlSchemaGetNodeContent(pctxt, (xmlNodePtr) attr);
7150 /* TODO: Maybe we need to normalize the value beforehand. */
7151 if (xmlStrEqual(attrValue, BAD_CAST(xmlChar *) "optional"))
7152 occurs = XML_SCHEMAS_ATTR_USE_OPTIONAL2;
7153 else if (xmlStrEqual(attrValue, BAD_CAST(xmlChar *) "prohibited"))
7154 occurs = XML_SCHEMAS_ATTR_USE_PROHIBITED0;
7155 else if (xmlStrEqual(attrValue, BAD_CAST(xmlChar *) "required"))
7156 occurs = XML_SCHEMAS_ATTR_USE_REQUIRED1;
7157 else {
7158 xmlSchemaPSimpleTypeErr(pctxt,
7159 XML_SCHEMAP_INVALID_ATTR_USE,
7160 NULL((void*)0), (xmlNodePtr) attr,
7161 NULL((void*)0), "(optional | prohibited | required)",
7162 attrValue, NULL((void*)0), NULL((void*)0), NULL((void*)0));
7163 }
7164 goto attr_next;
7165 } else if (xmlStrEqual(attr->name, BAD_CAST(xmlChar *) "default")) {
7166 /*
7167 * 3.2.3 : 1
7168 * default and fixed must not both be present.
7169 */
7170 if (defValue) {
7171 xmlSchemaPMutualExclAttrErr(pctxt,
7172 XML_SCHEMAP_SRC_ATTRIBUTE_1,
7173 NULL((void*)0), attr, "default", "fixed");
7174 } else {
7175 defValue = xmlSchemaGetNodeContent(pctxt, (xmlNodePtr) attr);
7176 defValueType = WXS_ATTR_DEF_VAL_DEFAULT1;
7177 }
7178 goto attr_next;
7179 } else if (xmlStrEqual(attr->name, BAD_CAST(xmlChar *) "fixed")) {
7180 /*
7181 * 3.2.3 : 1
7182 * default and fixed must not both be present.
7183 */
7184 if (defValue) {
7185 xmlSchemaPMutualExclAttrErr(pctxt,
7186 XML_SCHEMAP_SRC_ATTRIBUTE_1,
7187 NULL((void*)0), attr, "default", "fixed");
7188 } else {
7189 defValue = xmlSchemaGetNodeContent(pctxt, (xmlNodePtr) attr);
7190 defValueType = WXS_ATTR_DEF_VAL_FIXED2;
7191 }
7192 goto attr_next;
7193 }
7194 } else if (! xmlStrEqual(attr->ns->href, xmlSchemaNs))
7195 goto attr_next;
7196
7197 xmlSchemaPIllegalAttrErr(pctxt,
7198 XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL((void*)0), attr);
7199
7200attr_next:
7201 attr = attr->next;
7202 }
7203 /*
7204 * 3.2.3 : 2
7205 * If default and use are both present, use must have
7206 * the actual value optional.
7207 */
7208 if ((defValueType == WXS_ATTR_DEF_VAL_DEFAULT1) &&
7209 (occurs != XML_SCHEMAS_ATTR_USE_OPTIONAL2)) {
7210 xmlSchemaPSimpleTypeErr(pctxt,
7211 XML_SCHEMAP_SRC_ATTRIBUTE_2,
7212 NULL((void*)0), node, NULL((void*)0),
7213 "(optional | prohibited | required)", NULL((void*)0),
7214 "The value of the attribute 'use' must be 'optional' "
7215 "if the attribute 'default' is present",
7216 NULL((void*)0), NULL((void*)0));
7217 }
7218 /*
7219 * We want correct attributes.
7220 */
7221 if (nberrors != pctxt->nberrors)
7222 return(NULL((void*)0));
7223 if (! isRef) {
7224 xmlSchemaAttributePtr attrDecl;
7225
7226 /* TODO: move XML_SCHEMAS_QUALIF_ATTR to the parser. */
7227 if ((! hasForm) && (schema->flags & XML_SCHEMAS_QUALIF_ATTR1 << 1))
7228 ns = pctxt->targetNamespace;
7229 /*
7230 * 3.2.6 Schema Component Constraint: xsi: Not Allowed
7231 * TODO: Move this to the component layer.
7232 */
7233 if (xmlStrEqual(ns, xmlSchemaInstanceNs)) {
7234 xmlSchemaCustomErr(ACTXT_CAST(xmlSchemaAbstractCtxtPtr) pctxt,
7235 XML_SCHEMAP_NO_XSI,
7236 node, NULL((void*)0),
7237 "The target namespace must not match '%s'",
7238 xmlSchemaInstanceNs, NULL((void*)0));
7239 }
7240 attr = xmlSchemaGetPropNode(node, "name");
7241 if (attr == NULL((void*)0)) {
7242 xmlSchemaPMissingAttrErr(pctxt, XML_SCHEMAP_S4S_ATTR_MISSING,
7243 NULL((void*)0), node, "name", NULL((void*)0));
7244 return (NULL((void*)0));
7245 }
7246 if (xmlSchemaPValAttrNode(pctxt, NULL((void*)0), attr,
7247 xmlSchemaGetBuiltInType(XML_SCHEMAS_NCNAME), &name) != 0) {
7248 return (NULL((void*)0));
7249 }
7250 /*
7251 * 3.2.6 Schema Component Constraint: xmlns Not Allowed
7252 * TODO: Move this to the component layer.
7253 */
7254 if (xmlStrEqual(name, BAD_CAST(xmlChar *) "xmlns")) {
7255 xmlSchemaPSimpleTypeErr(pctxt,
7256 XML_SCHEMAP_NO_XMLNS,
7257 NULL((void*)0), (xmlNodePtr) attr,
7258 xmlSchemaGetBuiltInType(XML_SCHEMAS_NCNAME), NULL((void*)0), NULL((void*)0),
7259 "The value of the attribute must not match 'xmlns'",
7260 NULL((void*)0), NULL((void*)0));
7261 return (NULL((void*)0));
7262 }
7263 if (occurs == XML_SCHEMAS_ATTR_USE_PROHIBITED0)
7264 goto check_children;
7265 /*
7266 * Create the attribute use component.
7267 */
7268 use = xmlSchemaAddAttributeUse(pctxt, node);
7269 if (use == NULL((void*)0))
7270 return(NULL((void*)0));
7271 use->occurs = occurs;
7272 /*
7273 * Create the attribute declaration.
7274 */
7275 attrDecl = xmlSchemaAddAttribute(pctxt, schema, name, ns, node, 0);
7276 if (attrDecl == NULL((void*)0))
7277 return (NULL((void*)0));
7278 if (tmpName != NULL((void*)0)) {
7279 attrDecl->typeName = tmpName;
7280 attrDecl->typeNs = tmpNs;
7281 }
7282 use->attrDecl = attrDecl;
7283 /*
7284 * Value constraint.
7285 */
7286 if (defValue != NULL((void*)0)) {
7287 attrDecl->defValue = defValue;
7288 if (defValueType == WXS_ATTR_DEF_VAL_FIXED2)
7289 attrDecl->flags |= XML_SCHEMAS_ATTR_FIXED1 << 9;
7290 }
7291 } else if (occurs != XML_SCHEMAS_ATTR_USE_PROHIBITED0) {
7292 xmlSchemaQNameRefPtr ref;
7293
7294 /*
7295 * Create the attribute use component.
7296 */
7297 use = xmlSchemaAddAttributeUse(pctxt, node);
7298 if (use == NULL((void*)0))
7299 return(NULL((void*)0));
7300 /*
7301 * We need to resolve the reference at later stage.
7302 */
7303 WXS_ADD_PENDING(pctxt, use)xmlSchemaAddItemSize(&((pctxt)->constructor->pending
), 10, use)
;
7304 use->occurs = occurs;
7305 /*
7306 * Create a QName reference to the attribute declaration.
7307 */
7308 ref = xmlSchemaNewQNameRef(pctxt, XML_SCHEMA_TYPE_ATTRIBUTE,
7309 tmpName, tmpNs);
7310 if (ref == NULL((void*)0))
7311 return(NULL((void*)0));
7312 /*
7313 * Assign the reference. This will be substituted for the
7314 * referenced attribute declaration when the QName is resolved.
7315 */
7316 use->attrDecl = WXS_ATTR_CAST(xmlSchemaAttributePtr) ref;
7317 /*
7318 * Value constraint.
7319 */
7320 if (defValue != NULL((void*)0))
7321 use->defValue = defValue;
7322 if (defValueType == WXS_ATTR_DEF_VAL_FIXED2)
7323 use->flags |= XML_SCHEMA_ATTR_USE_FIXED1<<0;
7324 }
7325
7326check_children:
7327 /*
7328 * And now for the children...
7329 */
7330 child = node->children;
7331 if (occurs == XML_SCHEMAS_ATTR_USE_PROHIBITED0) {
7332 xmlSchemaAttributeUseProhibPtr prohib;
7333
7334 if (IS_SCHEMA(child, "annotation")((child != ((void*)0)) && (child->ns != ((void*)0)
) && (xmlStrEqual(child->name, (const xmlChar *) "annotation"
)) && (xmlStrEqual(child->ns->href, xmlSchemaNs
)))
) {
7335 xmlSchemaParseAnnotation(pctxt, child, 0);
7336 child = child->next;
7337 }
7338 if (child != NULL((void*)0)) {
7339 xmlSchemaPContentErr(pctxt,
7340 XML_SCHEMAP_S4S_ELEM_NOT_ALLOWED,
7341 NULL((void*)0), node, child, NULL((void*)0),
7342 "(annotation?)");
7343 }
7344 /*
7345 * Check for pointlessness of attribute prohibitions.
7346 */
7347 if (parentType == XML_SCHEMA_TYPE_ATTRIBUTEGROUP) {
7348 xmlSchemaCustomWarning(ACTXT_CAST(xmlSchemaAbstractCtxtPtr) pctxt,
7349 XML_SCHEMAP_WARN_ATTR_POINTLESS_PROH,
7350 node, NULL((void*)0),
7351 "Skipping attribute use prohibition, since it is "
7352 "pointless inside an <attributeGroup>",
7353 NULL((void*)0), NULL((void*)0), NULL((void*)0));
7354 return(NULL((void*)0));
7355 } else if (parentType == XML_SCHEMA_TYPE_EXTENSION) {
7356 xmlSchemaCustomWarning(ACTXT_CAST(xmlSchemaAbstractCtxtPtr) pctxt,
7357 XML_SCHEMAP_WARN_ATTR_POINTLESS_PROH,
7358 node, NULL((void*)0),
7359 "Skipping attribute use prohibition, since it is "
7360 "pointless when extending a type",
7361 NULL((void*)0), NULL((void*)0), NULL((void*)0));
7362 return(NULL((void*)0));
7363 }
7364 if (! isRef) {
7365 tmpName = name;
7366 tmpNs = ns;
7367 }
7368 /*
7369 * Check for duplicate attribute prohibitions.
7370 */
7371 if (uses) {
7372 int i;
7373
7374 for (i = 0; i < uses->nbItems; i++) {
7375 use = uses->items[i];
7376 if ((use->type == XML_SCHEMA_EXTRA_ATTR_USE_PROHIB) &&
7377 (tmpName == (WXS_ATTR_PROHIB_CAST(xmlSchemaAttributeUseProhibPtr) use)->name) &&
7378 (tmpNs == (WXS_ATTR_PROHIB_CAST(xmlSchemaAttributeUseProhibPtr) use)->targetNamespace))
7379 {
7380 xmlChar *str = NULL((void*)0);
7381
7382 xmlSchemaCustomWarning(ACTXT_CAST(xmlSchemaAbstractCtxtPtr) pctxt,
7383 XML_SCHEMAP_WARN_ATTR_POINTLESS_PROH,
7384 node, NULL((void*)0),
7385 "Skipping duplicate attribute use prohibition '%s'",
7386 xmlSchemaFormatQName(&str, tmpNs, tmpName),
7387 NULL((void*)0), NULL((void*)0));
7388 FREE_AND_NULL(str)if ((str) != ((void*)0)) { xmlFree((xmlChar *) (str)); str = (
(void*)0); }
7389 return(NULL((void*)0));
7390 }
7391 }
7392 }
7393 /*
7394 * Create the attribute prohibition helper component.
7395 */
7396 prohib = xmlSchemaAddAttributeUseProhib(pctxt);
7397 if (prohib == NULL((void*)0))
7398 return(NULL((void*)0));
7399 prohib->node = node;
7400 prohib->name = tmpName;
7401 prohib->targetNamespace = tmpNs;
7402 if (isRef) {
7403 /*
7404 * We need at least to resolve to the attribute declaration.
7405 */
7406 WXS_ADD_PENDING(pctxt, prohib)xmlSchemaAddItemSize(&((pctxt)->constructor->pending
), 10, prohib)
;
7407 }
7408 return(WXS_BASIC_CAST(xmlSchemaBasicItemPtr) prohib);
7409 } else {
7410 if (IS_SCHEMA(child, "annotation")((child != ((void*)0)) && (child->ns != ((void*)0)
) && (xmlStrEqual(child->name, (const xmlChar *) "annotation"
)) && (xmlStrEqual(child->ns->href, xmlSchemaNs
)))
) {
7411 /*
7412 * TODO: Should this go into the attr decl?
7413 */
7414 use->annot = xmlSchemaParseAnnotation(pctxt, child, 1);
7415 child = child->next;
7416 }
7417 if (isRef) {
7418 if (child != NULL((void*)0)) {
7419 if (IS_SCHEMA(child, "simpleType")((child != ((void*)0)) && (child->ns != ((void*)0)
) && (xmlStrEqual(child->name, (const xmlChar *) "simpleType"
)) && (xmlStrEqual(child->ns->href, xmlSchemaNs
)))
)
7420 /*
7421 * 3.2.3 : 3.2
7422 * If ref is present, then all of <simpleType>,
7423 * form and type must be absent.
7424 */
7425 xmlSchemaPContentErr(pctxt,
7426 XML_SCHEMAP_SRC_ATTRIBUTE_3_2,
7427 NULL((void*)0), node, child, NULL((void*)0),
7428 "(annotation?)");
7429 else
7430 xmlSchemaPContentErr(pctxt,
7431 XML_SCHEMAP_S4S_ELEM_NOT_ALLOWED,
7432 NULL((void*)0), node, child, NULL((void*)0),
7433 "(annotation?)");
7434 }
7435 } else {
7436 if (IS_SCHEMA(child, "simpleType")((child != ((void*)0)) && (child->ns != ((void*)0)
) && (xmlStrEqual(child->name, (const xmlChar *) "simpleType"
)) && (xmlStrEqual(child->ns->href, xmlSchemaNs
)))
) {
7437 if (WXS_ATTRUSE_DECL(use)((xmlSchemaAttributeUsePtr) (use))->attrDecl->typeName != NULL((void*)0)) {
7438 /*
7439 * 3.2.3 : 4
7440 * type and <simpleType> must not both be present.
7441 */
7442 xmlSchemaPContentErr(pctxt, XML_SCHEMAP_SRC_ATTRIBUTE_4,
7443 NULL((void*)0), node, child,
7444 "The attribute 'type' and the <simpleType> child "
7445 "are mutually exclusive", NULL((void*)0));
7446 } else
7447 WXS_ATTRUSE_TYPEDEF(use)(((xmlSchemaAttributeUsePtr) ((xmlSchemaAttributeUsePtr) use)
)->attrDecl)->subtypes
=
7448 xmlSchemaParseSimpleType(pctxt, schema, child, 0);
7449 child = child->next;
7450 }
7451 if (child != NULL((void*)0))
7452 xmlSchemaPContentErr(pctxt, XML_SCHEMAP_S4S_ELEM_NOT_ALLOWED,
7453 NULL((void*)0), node, child, NULL((void*)0),
7454 "(annotation?, simpleType?)");
7455 }
7456 }
7457 return (WXS_BASIC_CAST(xmlSchemaBasicItemPtr) use);
7458}
7459
7460
7461static xmlSchemaAttributePtr
7462xmlSchemaParseGlobalAttribute(xmlSchemaParserCtxtPtr pctxt,
7463 xmlSchemaPtr schema,
7464 xmlNodePtr node)
7465{
7466 const xmlChar *attrValue;
7467 xmlSchemaAttributePtr ret;
7468 xmlNodePtr child = NULL((void*)0);
7469 xmlAttrPtr attr;
7470
7471 /*
7472 * Note that the w3c spec assumes the schema to be validated with schema
7473 * for schemas beforehand.
7474 *
7475 * 3.2.3 Constraints on XML Representations of Attribute Declarations
7476 */
7477 if ((pctxt == NULL((void*)0)) || (schema == NULL((void*)0)) || (node == NULL((void*)0)))
7478 return (NULL((void*)0));
7479 /*
7480 * 3.2.3 : 3.1
7481 * One of ref or name must be present, but not both
7482 */
7483 attr = xmlSchemaGetPropNode(node, "name");
7484 if (attr == NULL((void*)0)) {
7485 xmlSchemaPMissingAttrErr(pctxt, XML_SCHEMAP_S4S_ATTR_MISSING,
7486 NULL((void*)0), node, "name", NULL((void*)0));
7487 return (NULL((void*)0));
7488 }
7489 if (xmlSchemaPValAttrNode(pctxt, NULL((void*)0), attr,
7490 xmlSchemaGetBuiltInType(XML_SCHEMAS_NCNAME), &attrValue) != 0) {
7491 return (NULL((void*)0));
7492 }
7493 /*
7494 * 3.2.6 Schema Component Constraint: xmlns Not Allowed
7495 * TODO: Move this to the component layer.
7496 */
7497 if (xmlStrEqual(attrValue, BAD_CAST(xmlChar *) "xmlns")) {
7498 xmlSchemaPSimpleTypeErr(pctxt,
7499 XML_SCHEMAP_NO_XMLNS,
7500 NULL((void*)0), (xmlNodePtr) attr,
7501 xmlSchemaGetBuiltInType(XML_SCHEMAS_NCNAME), NULL((void*)0), NULL((void*)0),
7502 "The value of the attribute must not match 'xmlns'",
7503 NULL((void*)0), NULL((void*)0));
7504 return (NULL((void*)0));
7505 }
7506 /*
7507 * 3.2.6 Schema Component Constraint: xsi: Not Allowed
7508 * TODO: Move this to the component layer.
7509 * Or better leave it here and add it to the component layer
7510 * if we have a schema construction API.
7511 */
7512 if (xmlStrEqual(pctxt->targetNamespace, xmlSchemaInstanceNs)) {
7513 xmlSchemaCustomErr(ACTXT_CAST(xmlSchemaAbstractCtxtPtr) pctxt,
7514 XML_SCHEMAP_NO_XSI, node, NULL((void*)0),
7515 "The target namespace must not match '%s'",
7516 xmlSchemaInstanceNs, NULL((void*)0));
7517 }
7518
7519 ret = xmlSchemaAddAttribute(pctxt, schema, attrValue,
7520 pctxt->targetNamespace, node, 1);
7521 if (ret == NULL((void*)0))
7522 return (NULL((void*)0));
7523 ret->flags |= XML_SCHEMAS_ATTR_GLOBAL1 << 0;
7524
7525 /*
7526 * Check for illegal attributes.
7527 */
7528 attr = node->properties;
7529 while (attr != NULL((void*)0)) {
7530 if (attr->ns == NULL((void*)0)) {
7531 if ((!xmlStrEqual(attr->name, BAD_CAST(xmlChar *) "id")) &&
7532 (!xmlStrEqual(attr->name, BAD_CAST(xmlChar *) "default")) &&
7533 (!xmlStrEqual(attr->name, BAD_CAST(xmlChar *) "fixed")) &&
7534 (!xmlStrEqual(attr->name, BAD_CAST(xmlChar *) "name")) &&
7535 (!xmlStrEqual(attr->name, BAD_CAST(xmlChar *) "type")))
7536 {
7537 xmlSchemaPIllegalAttrErr(pctxt,
7538 XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL((void*)0), attr);
7539 }
7540 } else if (xmlStrEqual(attr->ns->href, xmlSchemaNs)) {
7541 xmlSchemaPIllegalAttrErr(pctxt,
7542 XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL((void*)0), attr);
7543 }
7544 attr = attr->next;
7545 }
7546 xmlSchemaPValAttrQName(pctxt, schema, NULL((void*)0),
7547 node, "type", &ret->typeNs, &ret->typeName);
7548
7549 xmlSchemaPValAttrID(pctxt, node, BAD_CAST(xmlChar *) "id");
7550 /*
7551 * Attribute "fixed".
7552 */
7553 ret->defValue = xmlSchemaGetProp(pctxt, node, "fixed");
7554 if (ret->defValue != NULL((void*)0))
7555 ret->flags |= XML_SCHEMAS_ATTR_FIXED1 << 9;
7556 /*
7557 * Attribute "default".
7558 */
7559 attr = xmlSchemaGetPropNode(node, "default");
7560 if (attr != NULL((void*)0)) {
7561 /*
7562 * 3.2.3 : 1
7563 * default and fixed must not both be present.
7564 */
7565 if (ret->flags & XML_SCHEMAS_ATTR_FIXED1 << 9) {
7566 xmlSchemaPMutualExclAttrErr(pctxt, XML_SCHEMAP_SRC_ATTRIBUTE_1,
7567 WXS_BASIC_CAST(xmlSchemaBasicItemPtr) ret, attr, "default", "fixed");
7568 } else
7569 ret->defValue = xmlSchemaGetNodeContent(pctxt, (xmlNodePtr) attr);
7570 }
7571 /*
7572 * And now for the children...
7573 */
7574 child = node->children;
7575 if (IS_SCHEMA(child, "annotation")((child != ((void*)0)) && (child->ns != ((void*)0)
) && (xmlStrEqual(child->name, (const xmlChar *) "annotation"
)) && (xmlStrEqual(child->ns->href, xmlSchemaNs
)))
) {
7576 ret->annot = xmlSchemaParseAnnotation(pctxt, child, 1);
7577 child = child->next;
7578 }
7579 if (IS_SCHEMA(child, "simpleType")((child != ((void*)0)) && (child->ns != ((void*)0)
) && (xmlStrEqual(child->name, (const xmlChar *) "simpleType"
)) && (xmlStrEqual(child->ns->href, xmlSchemaNs
)))
) {
7580 if (ret->typeName != NULL((void*)0)) {
7581 /*
7582 * 3.2.3 : 4
7583 * type and <simpleType> must not both be present.
7584 */
7585 xmlSchemaPContentErr(pctxt, XML_SCHEMAP_SRC_ATTRIBUTE_4,
7586 NULL((void*)0), node, child,
7587 "The attribute 'type' and the <simpleType> child "
7588 "are mutually exclusive", NULL((void*)0));
7589 } else
7590 ret->subtypes = xmlSchemaParseSimpleType(pctxt, schema, child, 0);
7591 child = child->next;
7592 }
7593 if (child != NULL((void*)0))
7594 xmlSchemaPContentErr(pctxt, XML_SCHEMAP_S4S_ELEM_NOT_ALLOWED,
7595 NULL((void*)0), node, child, NULL((void*)0),
7596 "(annotation?, simpleType?)");
7597
7598 return (ret);
7599}
7600
7601/**
7602 * xmlSchemaParseAttributeGroupRef:
7603 * @ctxt: a schema validation context
7604 * @schema: the schema being built
7605 * @node: a subtree containing XML Schema information
7606 *
7607 * Parse an attribute group definition reference.
7608 * Note that a reference to an attribute group does not
7609 * correspond to any component at all.
7610 * *WARNING* this interface is highly subject to change
7611 *
7612 * Returns the attribute group or NULL in case of error.
7613 */
7614static xmlSchemaQNameRefPtr
7615xmlSchemaParseAttributeGroupRef(xmlSchemaParserCtxtPtr pctxt,
7616 xmlSchemaPtr schema,
7617 xmlNodePtr node)
7618{
7619 xmlSchemaQNameRefPtr ret;
7620 xmlNodePtr child = NULL((void*)0);
7621 xmlAttrPtr attr;
7622 const xmlChar *refNs = NULL((void*)0), *ref = NULL((void*)0);
7623
7624 if ((pctxt == NULL((void*)0)) || (schema == NULL((void*)0)) || (node == NULL((void*)0)))
7625 return (NULL((void*)0));
7626
7627 attr = xmlSchemaGetPropNode(node, "ref");
7628 if (attr == NULL((void*)0)) {
7629 xmlSchemaPMissingAttrErr(pctxt,
7630 XML_SCHEMAP_S4S_ATTR_MISSING,
7631 NULL((void*)0), node, "ref", NULL((void*)0));
7632 return (NULL((void*)0));
7633 }
7634 xmlSchemaPValAttrNodeQName(pctxt, schema,
7635 NULL((void*)0), attr, &refNs, &ref);
7636 if (xmlSchemaCheckReference(pctxt, schema, node, attr, refNs) != 0)
7637 return(NULL((void*)0));
7638
7639 /*
7640 * Check for illegal attributes.
7641 */
7642 attr = node->properties;
7643 while (attr != NULL((void*)0)) {
7644 if (attr->ns == NULL((void*)0)) {
7645 if ((!xmlStrEqual(attr->name, BAD_CAST(xmlChar *) "ref")) &&
7646 (!xmlStrEqual(attr->name, BAD_CAST(xmlChar *) "id")))
7647 {
7648 xmlSchemaPIllegalAttrErr(pctxt,
7649 XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL((void*)0), attr);
7650 }
7651 } else if (xmlStrEqual(attr->ns->href, xmlSchemaNs)) {
7652 xmlSchemaPIllegalAttrErr(pctxt,
7653 XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL((void*)0), attr);
7654 }
7655 attr = attr->next;
7656 }
7657 /* Attribute ID */
7658 xmlSchemaPValAttrID(pctxt, node, BAD_CAST(xmlChar *) "id");
7659
7660 /*
7661 * And now for the children...
7662 */
7663 child = node->children;
7664 if (IS_SCHEMA(child, "annotation")((child != ((void*)0)) && (child->ns != ((void*)0)
) && (xmlStrEqual(child->name, (const xmlChar *) "annotation"
)) && (xmlStrEqual(child->ns->href, xmlSchemaNs
)))
) {
7665 /*
7666 * TODO: We do not have a place to store the annotation, do we?
7667 */
7668 xmlSchemaParseAnnotation(pctxt, child, 0);
7669 child = child->next;
7670 }
7671 if (child != NULL((void*)0)) {
7672 xmlSchemaPContentErr(pctxt,
7673 XML_SCHEMAP_S4S_ELEM_NOT_ALLOWED,
7674 NULL((void*)0), node, child, NULL((void*)0),
7675 "(annotation?)");
7676 }
7677
7678 /*
7679 * Handle attribute group redefinitions.
7680 */
7681 if (pctxt->isRedefine && pctxt->redef &&
7682 (pctxt->redef->item->type ==
7683 XML_SCHEMA_TYPE_ATTRIBUTEGROUP) &&
7684 (ref == pctxt->redef->refName) &&
7685 (refNs == pctxt->redef->refTargetNs))
7686 {
7687 /*
7688 * SPEC src-redefine:
7689 * (7.1) "If it has an <attributeGroup> among its contents
7690 * the `actual value` of whose ref [attribute] is the same
7691 * as the `actual value` of its own name attribute plus
7692 * target namespace, then it must have exactly one such group."
7693 */
7694 if (pctxt->redefCounter != 0) {
7695 xmlChar *str = NULL((void*)0);
7696
7697 xmlSchemaCustomErr(ACTXT_CAST(xmlSchemaAbstractCtxtPtr) pctxt,
7698 XML_SCHEMAP_SRC_REDEFINE, node, NULL((void*)0),
7699 "The redefining attribute group definition "
7700 "'%s' must not contain more than one "
7701 "reference to the redefined definition",
7702 xmlSchemaFormatQName(&str, refNs, ref), NULL((void*)0));
7703 FREE_AND_NULL(str)if ((str) != ((void*)0)) { xmlFree((xmlChar *) (str)); str = (
(void*)0); }
;
7704 return(NULL((void*)0));
7705 }
7706 pctxt->redefCounter++;
7707 /*
7708 * URGENT TODO: How to ensure that the reference will not be
7709 * handled by the normal component resolution mechanism?
7710 */
7711 ret = xmlSchemaNewQNameRef(pctxt,
7712 XML_SCHEMA_TYPE_ATTRIBUTEGROUP, ref, refNs);
7713 if (ret == NULL((void*)0))
7714 return(NULL((void*)0));
7715 ret->node = node;
7716 pctxt->redef->reference = WXS_BASIC_CAST(xmlSchemaBasicItemPtr) ret;
7717 } else {
7718 /*
7719 * Create a QName-reference helper component. We will substitute this
7720 * component for the attribute uses of the referenced attribute group
7721 * definition.
7722 */
7723 ret = xmlSchemaNewQNameRef(pctxt,
7724 XML_SCHEMA_TYPE_ATTRIBUTEGROUP, ref, refNs);
7725 if (ret == NULL((void*)0))
7726 return(NULL((void*)0));
7727 ret->node = node;
7728 /* Add to pending items, to be able to resolve the reference. */
7729 WXS_ADD_PENDING(pctxt, ret)xmlSchemaAddItemSize(&((pctxt)->constructor->pending
), 10, ret)
;
7730 }
7731 return (ret);
7732}
7733
7734/**
7735 * xmlSchemaParseAttributeGroupDefinition:
7736 * @pctxt: a schema validation context
7737 * @schema: the schema being built
7738 * @node: a subtree containing XML Schema information
7739 *
7740 * parse a XML schema Attribute Group declaration
7741 * *WARNING* this interface is highly subject to change
7742 *
7743 * Returns the attribute group definition or NULL in case of error.
7744 */
7745static xmlSchemaAttributeGroupPtr
7746xmlSchemaParseAttributeGroupDefinition(xmlSchemaParserCtxtPtr pctxt,
7747 xmlSchemaPtr schema,
7748 xmlNodePtr node)
7749{
7750 const xmlChar *name;
7751 xmlSchemaAttributeGroupPtr ret;
7752 xmlNodePtr child = NULL((void*)0);
7753 xmlAttrPtr attr;
7754 int hasRefs = 0;
7755
7756 if ((pctxt == NULL((void*)0)) || (schema == NULL((void*)0)) || (node == NULL((void*)0)))
7757 return (NULL((void*)0));
7758
7759 attr = xmlSchemaGetPropNode(node, "name");
7760 if (attr == NULL((void*)0)) {
7761 xmlSchemaPMissingAttrErr(pctxt,
7762 XML_SCHEMAP_S4S_ATTR_MISSING,
7763 NULL((void*)0), node, "name", NULL((void*)0));
7764 return (NULL((void*)0));
7765 }
7766 /*
7767 * The name is crucial, exit if invalid.
7768 */
7769 if (xmlSchemaPValAttrNode(pctxt,
7770 NULL((void*)0), attr,
7771 xmlSchemaGetBuiltInType(XML_SCHEMAS_NCNAME), &name) != 0) {
7772 return (NULL((void*)0));
7773 }
7774 ret = xmlSchemaAddAttributeGroupDefinition(pctxt, schema,
7775 name, pctxt->targetNamespace, node);
7776 if (ret == NULL((void*)0))
7777 return (NULL((void*)0));
7778 /*
7779 * Check for illegal attributes.
7780 */
7781 attr = node->properties;
7782 while (attr != NULL((void*)0)) {
7783 if (attr->ns == NULL((void*)0)) {
7784 if ((!xmlStrEqual(attr->name, BAD_CAST(xmlChar *) "name")) &&
7785 (!xmlStrEqual(attr->name, BAD_CAST(xmlChar *) "id")))
7786 {
7787 xmlSchemaPIllegalAttrErr(pctxt,
7788 XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL((void*)0), attr);
7789 }
7790 } else if (xmlStrEqual(attr->ns->href, xmlSchemaNs)) {
7791 xmlSchemaPIllegalAttrErr(pctxt,
7792 XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL((void*)0), attr);
7793 }
7794 attr = attr->next;
7795 }
7796 /* Attribute ID */
7797 xmlSchemaPValAttrID(pctxt, node, BAD_CAST(xmlChar *) "id");
7798 /*
7799 * And now for the children...
7800 */
7801 child = node->children;
7802 if (IS_SCHEMA(child, "annotation")((child != ((void*)0)) && (child->ns != ((void*)0)
) && (xmlStrEqual(child->name, (const xmlChar *) "annotation"
)) && (xmlStrEqual(child->ns->href, xmlSchemaNs
)))
) {
7803 ret->annot = xmlSchemaParseAnnotation(pctxt, child, 1);
7804 child = child->next;
7805 }
7806 /*
7807 * Parse contained attribute decls/refs.
7808 */
7809 if (xmlSchemaParseLocalAttributes(pctxt, schema, &child,
7810 (xmlSchemaItemListPtr *) &(ret->attrUses),
7811 XML_SCHEMA_TYPE_ATTRIBUTEGROUP, &hasRefs) == -1)
7812 return(NULL((void*)0));
7813 if (hasRefs)
7814 ret->flags |= XML_SCHEMAS_ATTRGROUP_HAS_REFS1 << 4;
7815 /*
7816 * Parse the attribute wildcard.
7817 */
7818 if (IS_SCHEMA(child, "anyAttribute")((child != ((void*)0)) && (child->ns != ((void*)0)
) && (xmlStrEqual(child->name, (const xmlChar *) "anyAttribute"
)) && (xmlStrEqual(child->ns->href, xmlSchemaNs
)))
) {
7819 ret->attributeWildcard = xmlSchemaParseAnyAttribute(pctxt,
7820 schema, child);
7821 child = child->next;
7822 }
7823 if (child != NULL((void*)0)) {
7824 xmlSchemaPContentErr(pctxt,
7825 XML_SCHEMAP_S4S_ELEM_NOT_ALLOWED,
7826 NULL((void*)0), node, child, NULL((void*)0),
7827 "(annotation?, ((attribute | attributeGroup)*, anyAttribute?))");
7828 }
7829 return (ret);
7830}
7831
7832/**
7833 * xmlSchemaPValAttrFormDefault:
7834 * @value: the value
7835 * @flags: the flags to be modified
7836 * @flagQualified: the specific flag for "qualified"
7837 *
7838 * Returns 0 if the value is valid, 1 otherwise.
7839 */
7840static int
7841xmlSchemaPValAttrFormDefault(const xmlChar *value,
7842 int *flags,
7843 int flagQualified)
7844{
7845 if (xmlStrEqual(value, BAD_CAST(xmlChar *) "qualified")) {
7846 if ((*flags & flagQualified) == 0)
7847 *flags |= flagQualified;
7848 } else if (!xmlStrEqual(value, BAD_CAST(xmlChar *) "unqualified"))
7849 return (1);
7850
7851 return (0);
7852}
7853
7854/**
7855 * xmlSchemaPValAttrBlockFinal:
7856 * @value: the value
7857 * @flags: the flags to be modified
7858 * @flagAll: the specific flag for "#all"
7859 * @flagExtension: the specific flag for "extension"
7860 * @flagRestriction: the specific flag for "restriction"
7861 * @flagSubstitution: the specific flag for "substitution"
7862 * @flagList: the specific flag for "list"
7863 * @flagUnion: the specific flag for "union"
7864 *
7865 * Validates the value of the attribute "final" and "block". The value
7866 * is converted into the specified flag values and returned in @flags.
7867 *
7868 * Returns 0 if the value is valid, 1 otherwise.
7869 */
7870
7871static int
7872xmlSchemaPValAttrBlockFinal(const xmlChar *value,
7873 int *flags,
7874 int flagAll,
7875 int flagExtension,
7876 int flagRestriction,
7877 int flagSubstitution,
7878 int flagList,
7879 int flagUnion)
7880{
7881 int ret = 0;
7882
7883 /*
7884 * TODO: This does not check for duplicate entries.
7885 */
7886 if ((flags == NULL((void*)0)) || (value == NULL((void*)0)))
7887 return (-1);
7888 if (value[0] == 0)
7889 return (0);
7890 if (xmlStrEqual(value, BAD_CAST(xmlChar *) "#all")) {
7891 if (flagAll != -1)
7892 *flags |= flagAll;
7893 else {
7894 if (flagExtension != -1)
7895 *flags |= flagExtension;
7896 if (flagRestriction != -1)
7897 *flags |= flagRestriction;
7898 if (flagSubstitution != -1)
7899 *flags |= flagSubstitution;
7900 if (flagList != -1)
7901 *flags |= flagList;
7902 if (flagUnion != -1)
7903 *flags |= flagUnion;
7904 }
7905 } else {
7906 const xmlChar *end, *cur = value;
7907 xmlChar *item;
7908
7909 do {
7910 while (IS_BLANK_CH(*cur)(((*cur) == 0x20) || ((0x9 <= (*cur)) && ((*cur) <=
0xa)) || ((*cur) == 0xd))
)
7911 cur++;
7912 end = cur;
7913 while ((*end != 0) && (!(IS_BLANK_CH(*end)(((*end) == 0x20) || ((0x9 <= (*end)) && ((*end) <=
0xa)) || ((*end) == 0xd))
)))
7914 end++;
7915 if (end == cur)
7916 break;
7917 item = xmlStrndup(cur, end - cur);
7918 if (xmlStrEqual(item, BAD_CAST(xmlChar *) "extension")) {
7919 if (flagExtension != -1) {
7920 if ((*flags & flagExtension) == 0)
7921 *flags |= flagExtension;
7922 } else
7923 ret = 1;
7924 } else if (xmlStrEqual(item, BAD_CAST(xmlChar *) "restriction")) {
7925 if (flagRestriction != -1) {
7926 if ((*flags & flagRestriction) == 0)
7927 *flags |= flagRestriction;
7928 } else
7929 ret = 1;
7930 } else if (xmlStrEqual(item, BAD_CAST(xmlChar *) "substitution")) {
7931 if (flagSubstitution != -1) {
7932 if ((*flags & flagSubstitution) == 0)
7933 *flags |= flagSubstitution;
7934 } else
7935 ret = 1;
7936 } else if (xmlStrEqual(item, BAD_CAST(xmlChar *) "list")) {
7937 if (flagList != -1) {
7938 if ((*flags & flagList) == 0)
7939 *flags |= flagList;
7940 } else
7941 ret = 1;
7942 } else if (xmlStrEqual(item, BAD_CAST(xmlChar *) "union")) {
7943 if (flagUnion != -1) {
7944 if ((*flags & flagUnion) == 0)
7945 *flags |= flagUnion;
7946 } else
7947 ret = 1;
7948 } else
7949 ret = 1;
7950 if (item != NULL((void*)0))
7951 xmlFree(item);
7952 cur = end;
7953 } while ((ret == 0) && (*cur != 0));
7954 }
7955
7956 return (ret);
7957}
7958
7959static int
7960xmlSchemaCheckCSelectorXPath(xmlSchemaParserCtxtPtr ctxt,
7961 xmlSchemaIDCPtr idc,
7962 xmlSchemaIDCSelectPtr selector,
7963 xmlAttrPtr attr,
7964 int isField)
7965{
7966 xmlNodePtr node;
7967
7968 /*
7969 * c-selector-xpath:
7970 * Schema Component Constraint: Selector Value OK
7971 *
7972 * TODO: 1 The {selector} must be a valid XPath expression, as defined
7973 * in [XPath].
7974 */
7975 if (selector == NULL((void*)0)) {
7976 xmlSchemaPErr(ctxt, idc->node,
7977 XML_SCHEMAP_INTERNAL,
7978 "Internal error: xmlSchemaCheckCSelectorXPath, "
7979 "the selector is not specified.\n", NULL((void*)0), NULL((void*)0));
7980 return (-1);
7981 }
7982 if (attr == NULL((void*)0))
7983 node = idc->node;
7984 else
7985 node = (xmlNodePtr) attr;
7986 if (selector->xpath == NULL((void*)0)) {
7987 xmlSchemaPCustomErr(ctxt,
7988 /* TODO: Adjust error code. */
7989 XML_SCHEMAP_S4S_ATTR_INVALID_VALUE,
7990 NULL((void*)0), node,
7991 "The XPath expression of the selector is not valid", NULL((void*)0));
7992 return (XML_SCHEMAP_S4S_ATTR_INVALID_VALUE);
7993 } else {
7994 const xmlChar **nsArray = NULL((void*)0);
7995 xmlNsPtr *nsList = NULL((void*)0);
7996 /*
7997 * Compile the XPath expression.
7998 */
7999 /*
8000 * TODO: We need the array of in-scope namespaces for compilation.
8001 * TODO: Call xmlPatterncompile with different options for selector/
8002 * field.
8003 */
8004 if (attr == NULL((void*)0))
8005 nsList = NULL((void*)0);
8006 else
8007 nsList = xmlGetNsList(attr->doc, attr->parent);
8008 /*
8009 * Build an array of prefixes and namespaces.
8010 */
8011 if (nsList != NULL((void*)0)) {
8012 int i, count = 0;
8013
8014 for (i = 0; nsList[i] != NULL((void*)0); i++)
8015 count++;
8016
8017 nsArray = (const xmlChar **) xmlMalloc(
8018 (count * 2 + 1) * sizeof(const xmlChar *));
8019 if (nsArray == NULL((void*)0)) {
8020 xmlSchemaPErrMemory(ctxt, "allocating a namespace array",
8021 NULL((void*)0));
8022 xmlFree(nsList);
8023 return (-1);
8024 }
8025 for (i = 0; i < count; i++) {
8026 nsArray[2 * i] = nsList[i]->href;
8027 nsArray[2 * i + 1] = nsList[i]->prefix;
8028 }
8029 nsArray[count * 2] = NULL((void*)0);
8030 xmlFree(nsList);
8031 }
8032 /*
8033 * TODO: Differentiate between "selector" and "field".
8034 */
8035 if (isField)
8036 selector->xpathComp = (void *) xmlPatterncompile(selector->xpath,
8037 NULL((void*)0), XML_PATTERN_XSFIELD, nsArray);
8038 else
8039 selector->xpathComp = (void *) xmlPatterncompile(selector->xpath,
8040 NULL((void*)0), XML_PATTERN_XSSEL, nsArray);
8041 if (nsArray != NULL((void*)0))
8042 xmlFree((xmlChar **) nsArray);
8043
8044 if (selector->xpathComp == NULL((void*)0)) {
8045 xmlSchemaPCustomErr(ctxt,
8046 /* TODO: Adjust error code? */
8047 XML_SCHEMAP_S4S_ATTR_INVALID_VALUE,
8048 NULL((void*)0), node,
8049 "The XPath expression '%s' could not be "
8050 "compiled", selector->xpath);
8051 return (XML_SCHEMAP_S4S_ATTR_INVALID_VALUE);
8052 }
8053 }
8054 return (0);
8055}
8056
8057#define ADD_ANNOTATION(annot)xmlSchemaAnnotPtr cur = item->annot; if (item->annot ==
((void*)0)) { item->annot = annot; return (annot); } cur =
item->annot; if (cur->next != ((void*)0)) { cur = cur->
next; } cur->next = annot;
\
8058 xmlSchemaAnnotPtr cur = item->annot; \
8059 if (item->annot == NULL((void*)0)) { \
8060 item->annot = annot; \
8061 return (annot); \
8062 } \
8063 cur = item->annot; \
8064 if (cur->next != NULL((void*)0)) { \
8065 cur = cur->next; \
8066 } \
8067 cur->next = annot;
8068
8069/**
8070 * xmlSchemaAssignAnnotation:
8071 * @item: the schema component
8072 * @annot: the annotation
8073 *
8074 * Adds the annotation to the given schema component.
8075 *
8076 * Returns the given annotation.
8077 */
8078static xmlSchemaAnnotPtr
8079xmlSchemaAddAnnotation(xmlSchemaAnnotItemPtr annItem,
8080 xmlSchemaAnnotPtr annot)
8081{
8082 if ((annItem == NULL((void*)0)) || (annot == NULL((void*)0)))
8083 return (NULL((void*)0));
8084 switch (annItem->type) {
8085 case XML_SCHEMA_TYPE_ELEMENT: {
8086 xmlSchemaElementPtr item = (xmlSchemaElementPtr) annItem;
8087 ADD_ANNOTATION(annot)xmlSchemaAnnotPtr cur = item->annot; if (item->annot ==
((void*)0)) { item->annot = annot; return (annot); } cur =
item->annot; if (cur->next != ((void*)0)) { cur = cur->
next; } cur->next = annot;
8088 }
8089 break;
8090 case XML_SCHEMA_TYPE_ATTRIBUTE: {
8091 xmlSchemaAttributePtr item = (xmlSchemaAttributePtr) annItem;
8092 ADD_ANNOTATION(annot)xmlSchemaAnnotPtr cur = item->annot; if (item->annot ==
((void*)0)) { item->annot = annot; return (annot); } cur =
item->annot; if (cur->next != ((void*)0)) { cur = cur->
next; } cur->next = annot;
8093 }
8094 break;
8095 case XML_SCHEMA_TYPE_ANY_ATTRIBUTE:
8096 case XML_SCHEMA_TYPE_ANY: {
8097 xmlSchemaWildcardPtr item = (xmlSchemaWildcardPtr) annItem;
8098 ADD_ANNOTATION(annot)xmlSchemaAnnotPtr cur = item->annot; if (item->annot ==
((void*)0)) { item->annot = annot; return (annot); } cur =
item->annot; if (cur->next != ((void*)0)) { cur = cur->
next; } cur->next = annot;
8099 }
8100 break;
8101 case XML_SCHEMA_TYPE_PARTICLE:
8102 case XML_SCHEMA_TYPE_IDC_KEY:
8103 case XML_SCHEMA_TYPE_IDC_KEYREF:
8104 case XML_SCHEMA_TYPE_IDC_UNIQUE: {
8105 xmlSchemaAnnotItemPtr item = (xmlSchemaAnnotItemPtr) annItem;
8106 ADD_ANNOTATION(annot)xmlSchemaAnnotPtr cur = item->annot; if (item->annot ==
((void*)0)) { item->annot = annot; return (annot); } cur =
item->annot; if (cur->next != ((void*)0)) { cur = cur->
next; } cur->next = annot;
8107 }
8108 break;
8109 case XML_SCHEMA_TYPE_ATTRIBUTEGROUP: {
8110 xmlSchemaAttributeGroupPtr item =
8111 (xmlSchemaAttributeGroupPtr) annItem;
8112 ADD_ANNOTATION(annot)xmlSchemaAnnotPtr cur = item->annot; if (item->annot ==
((void*)0)) { item->annot = annot; return (annot); } cur =
item->annot; if (cur->next != ((void*)0)) { cur = cur->
next; } cur->next = annot;
8113 }
8114 break;
8115 case XML_SCHEMA_TYPE_NOTATION: {
8116 xmlSchemaNotationPtr item = (xmlSchemaNotationPtr) annItem;
8117 ADD_ANNOTATION(annot)xmlSchemaAnnotPtr cur = item->annot; if (item->annot ==
((void*)0)) { item->annot = annot; return (annot); } cur =
item->annot; if (cur->next != ((void*)0)) { cur = cur->
next; } cur->next = annot;
8118 }
8119 break;
8120 case XML_SCHEMA_FACET_MININCLUSIVE:
8121 case XML_SCHEMA_FACET_MINEXCLUSIVE:
8122 case XML_SCHEMA_FACET_MAXINCLUSIVE:
8123 case XML_SCHEMA_FACET_MAXEXCLUSIVE:
8124 case XML_SCHEMA_FACET_TOTALDIGITS:
8125 case XML_SCHEMA_FACET_FRACTIONDIGITS:
8126 case XML_SCHEMA_FACET_PATTERN:
8127 case XML_SCHEMA_FACET_ENUMERATION:
8128 case XML_SCHEMA_FACET_WHITESPACE:
8129 case XML_SCHEMA_FACET_LENGTH:
8130 case XML_SCHEMA_FACET_MAXLENGTH:
8131 case XML_SCHEMA_FACET_MINLENGTH: {
8132 xmlSchemaFacetPtr item = (xmlSchemaFacetPtr) annItem;
8133 ADD_ANNOTATION(annot)xmlSchemaAnnotPtr cur = item->annot; if (item->annot ==
((void*)0)) { item->annot = annot; return (annot); } cur =
item->annot; if (cur->next != ((void*)0)) { cur = cur->
next; } cur->next = annot;
8134 }
8135 break;
8136 case XML_SCHEMA_TYPE_SIMPLE:
8137 case XML_SCHEMA_TYPE_COMPLEX: {
8138 xmlSchemaTypePtr item = (xmlSchemaTypePtr) annItem;
8139 ADD_ANNOTATION(annot)xmlSchemaAnnotPtr cur = item->annot; if (item->annot ==
((void*)0)) { item->annot = annot; return (annot); } cur =
item->annot; if (cur->next != ((void*)0)) { cur = cur->
next; } cur->next = annot;
8140 }
8141 break;
8142 case XML_SCHEMA_TYPE_GROUP: {
8143 xmlSchemaModelGroupDefPtr item = (xmlSchemaModelGroupDefPtr) annItem;
8144 ADD_ANNOTATION(annot)xmlSchemaAnnotPtr cur = item->annot; if (item->annot ==
((void*)0)) { item->annot = annot; return (annot); } cur =
item->annot; if (cur->next != ((void*)0)) { cur = cur->
next; } cur->next = annot;
8145 }
8146 break;
8147 case XML_SCHEMA_TYPE_SEQUENCE:
8148 case XML_SCHEMA_TYPE_CHOICE:
8149 case XML_SCHEMA_TYPE_ALL: {
8150 xmlSchemaModelGroupPtr item = (xmlSchemaModelGroupPtr) annItem;
8151 ADD_ANNOTATION(annot)xmlSchemaAnnotPtr cur = item->annot; if (item->annot ==
((void*)0)) { item->annot = annot; return (annot); } cur =
item->annot; if (cur->next != ((void*)0)) { cur = cur->
next; } cur->next = annot;
8152 }
8153 break;
8154 default:
8155 xmlSchemaPCustomErr(NULL((void*)0),
8156 XML_SCHEMAP_INTERNAL,
8157 NULL((void*)0), NULL((void*)0),
8158 "Internal error: xmlSchemaAddAnnotation, "
8159 "The item is not a annotated schema component", NULL((void*)0));
8160 break;
8161 }
8162 return (annot);
8163}
8164
8165/**
8166 * xmlSchemaParseIDCSelectorAndField:
8167 * @ctxt: a schema validation context
8168 * @schema: the schema being built
8169 * @node: a subtree containing XML Schema information
8170 *
8171 * Parses a XML Schema identity-constraint definition's
8172 * <selector> and <field> elements.
8173 *
8174 * Returns the parsed identity-constraint definition.
8175 */
8176static xmlSchemaIDCSelectPtr
8177xmlSchemaParseIDCSelectorAndField(xmlSchemaParserCtxtPtr ctxt,
8178 xmlSchemaIDCPtr idc,
8179 xmlNodePtr node,
8180 int isField)
8181{
8182 xmlSchemaIDCSelectPtr item;
8183 xmlNodePtr child = NULL((void*)0);
8184 xmlAttrPtr attr;
8185
8186 /*
8187 * Check for illegal attributes.
8188 */
8189 attr = node->properties;
8190 while (attr != NULL((void*)0)) {
8191 if (attr->ns == NULL((void*)0)) {
8192 if ((!xmlStrEqual(attr->name, BAD_CAST(xmlChar *) "id")) &&
8193 (!xmlStrEqual(attr->name, BAD_CAST(xmlChar *) "xpath"))) {
8194 xmlSchemaPIllegalAttrErr(ctxt,
8195 XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL((void*)0), attr);
8196 }
8197 } else if (xmlStrEqual(attr->ns->href, xmlSchemaNs)) {
8198 xmlSchemaPIllegalAttrErr(ctxt,
8199 XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL((void*)0), attr);
8200 }
8201 attr = attr->next;
8202 }
8203 /*
8204 * Create the item.
8205 */
8206 item = (xmlSchemaIDCSelectPtr) xmlMalloc(sizeof(xmlSchemaIDCSelect));
8207 if (item == NULL((void*)0)) {
8208 xmlSchemaPErrMemory(ctxt,
8209 "allocating a 'selector' of an identity-constraint definition",
8210 NULL((void*)0));
8211 return (NULL((void*)0));
8212 }
8213 memset(item, 0, sizeof(xmlSchemaIDCSelect));
8214 /*
8215 * Attribute "xpath" (mandatory).
8216 */
8217 attr = xmlSchemaGetPropNode(node, "xpath");
8218 if (attr == NULL((void*)0)) {
8219 xmlSchemaPMissingAttrErr(ctxt,
8220 XML_SCHEMAP_S4S_ATTR_MISSING,
8221 NULL((void*)0), node,
8222 "name", NULL((void*)0));
8223 } else {
8224 item->xpath = xmlSchemaGetNodeContent(ctxt, (xmlNodePtr) attr);
8225 /*
8226 * URGENT TODO: "field"s have an other syntax than "selector"s.
8227 */
8228
8229 if (xmlSchemaCheckCSelectorXPath(ctxt, idc, item, attr,
8230 isField) == -1) {
8231 xmlSchemaPErr(ctxt,
8232 (xmlNodePtr) attr,
8233 XML_SCHEMAP_INTERNAL,
8234 "Internal error: xmlSchemaParseIDCSelectorAndField, "
8235 "validating the XPath expression of a IDC selector.\n",
8236 NULL((void*)0), NULL((void*)0));
8237 }
8238
8239 }
8240 xmlSchemaPValAttrID(ctxt, node, BAD_CAST(xmlChar *) "id");
8241 /*
8242 * And now for the children...
8243 */
8244 child = node->children;
8245 if (IS_SCHEMA(child, "annotation")((child != ((void*)0)) && (child->ns != ((void*)0)
) && (xmlStrEqual(child->name, (const xmlChar *) "annotation"
)) && (xmlStrEqual(child->ns->href, xmlSchemaNs
)))
) {
8246 /*
8247 * Add the annotation to the parent IDC.
8248 */
8249 xmlSchemaAddAnnotation((xmlSchemaAnnotItemPtr) idc,
8250 xmlSchemaParseAnnotation(ctxt, child, 1));
8251 child = child->next;
8252 }
8253 if (child != NULL((void*)0)) {
8254 xmlSchemaPContentErr(ctxt,
8255 XML_SCHEMAP_S4S_ELEM_NOT_ALLOWED,
8256 NULL((void*)0), node, child,
8257 NULL((void*)0), "(annotation?)");
8258 }
8259
8260 return (item);
8261}
8262
8263/**
8264 * xmlSchemaParseIDC:
8265 * @ctxt: a schema validation context
8266 * @schema: the schema being built
8267 * @node: a subtree containing XML Schema information
8268 *
8269 * Parses a XML Schema identity-constraint definition.
8270 *
8271 * Returns the parsed identity-constraint definition.
8272 */
8273static xmlSchemaIDCPtr
8274xmlSchemaParseIDC(xmlSchemaParserCtxtPtr ctxt,
8275 xmlSchemaPtr schema,
8276 xmlNodePtr node,
8277 xmlSchemaTypeType idcCategory,
8278 const xmlChar *targetNamespace)
8279{
8280 xmlSchemaIDCPtr item = NULL((void*)0);
8281 xmlNodePtr child = NULL((void*)0);
8282 xmlAttrPtr attr;
8283 const xmlChar *name = NULL((void*)0);
8284 xmlSchemaIDCSelectPtr field = NULL((void*)0), lastField = NULL((void*)0);
8285
8286 /*
8287 * Check for illegal attributes.
8288 */
8289 attr = node->properties;
8290 while (attr != NULL((void*)0)) {
8291 if (attr->ns == NULL((void*)0)) {
8292 if ((!xmlStrEqual(attr->name, BAD_CAST(xmlChar *) "id")) &&
8293 (!xmlStrEqual(attr->name, BAD_CAST(xmlChar *) "name")) &&
8294 ((idcCategory != XML_SCHEMA_TYPE_IDC_KEYREF) ||
8295 (!xmlStrEqual(attr->name, BAD_CAST(xmlChar *) "refer")))) {
8296 xmlSchemaPIllegalAttrErr(ctxt,
8297 XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL((void*)0), attr);
8298 }
8299 } else if (xmlStrEqual(attr->ns->href, xmlSchemaNs)) {
8300 xmlSchemaPIllegalAttrErr(ctxt,
8301 XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL((void*)0), attr);
8302 }
8303 attr = attr->next;
8304 }
8305 /*
8306 * Attribute "name" (mandatory).
8307 */
8308 attr = xmlSchemaGetPropNode(node, "name");
8309 if (attr == NULL((void*)0)) {
8310 xmlSchemaPMissingAttrErr(ctxt,
8311 XML_SCHEMAP_S4S_ATTR_MISSING,
8312 NULL((void*)0), node,
8313 "name", NULL((void*)0));
8314 return (NULL((void*)0));
8315 } else if (xmlSchemaPValAttrNode(ctxt,
8316 NULL((void*)0), attr,
8317 xmlSchemaGetBuiltInType(XML_SCHEMAS_NCNAME), &name) != 0) {
8318 return (NULL((void*)0));
8319 }
8320 /* Create the component. */
8321 item = xmlSchemaAddIDC(ctxt, schema, name, targetNamespace,
8322 idcCategory, node);
8323 if (item == NULL((void*)0))
8324 return(NULL((void*)0));
8325
8326 xmlSchemaPValAttrID(ctxt, node, BAD_CAST(xmlChar *) "id");
8327 if (idcCategory == XML_SCHEMA_TYPE_IDC_KEYREF) {
8328 /*
8329 * Attribute "refer" (mandatory).
8330 */
8331 attr = xmlSchemaGetPropNode(node, "refer");
8332 if (attr == NULL((void*)0)) {
8333 xmlSchemaPMissingAttrErr(ctxt,
8334 XML_SCHEMAP_S4S_ATTR_MISSING,
8335 NULL((void*)0), node,
8336 "refer", NULL((void*)0));
8337 } else {
8338 /*
8339 * Create a reference item.
8340 */
8341 item->ref = xmlSchemaNewQNameRef(ctxt, XML_SCHEMA_TYPE_IDC_KEY,
8342 NULL((void*)0), NULL((void*)0));
8343 if (item->ref == NULL((void*)0))
8344 return (NULL((void*)0));
8345 xmlSchemaPValAttrNodeQName(ctxt, schema,
8346 NULL((void*)0), attr,
8347 &(item->ref->targetNamespace),
8348 &(item->ref->name));
8349 xmlSchemaCheckReference(ctxt, schema, node, attr,
8350 item->ref->targetNamespace);
8351 }
8352 }
8353 /*
8354 * And now for the children...
8355 */
8356 child = node->children;
8357 if (IS_SCHEMA(child, "annotation")((child != ((void*)0)) && (child->ns != ((void*)0)
) && (xmlStrEqual(child->name, (const xmlChar *) "annotation"
)) && (xmlStrEqual(child->ns->href, xmlSchemaNs
)))
) {
8358 item->annot = xmlSchemaParseAnnotation(ctxt, child, 1);
8359 child = child->next;
8360 }
8361 if (child == NULL((void*)0)) {
8362 xmlSchemaPContentErr(ctxt,
8363 XML_SCHEMAP_S4S_ELEM_MISSING,
8364 NULL((void*)0), node, child,
8365 "A child element is missing",
8366 "(annotation?, (selector, field+))");
8367 }
8368 /*
8369 * Child element <selector>.
8370 */
8371 if (IS_SCHEMA(child, "selector")((child != ((void*)0)) && (child->ns != ((void*)0)
) && (xmlStrEqual(child->name, (const xmlChar *) "selector"
)) && (xmlStrEqual(child->ns->href, xmlSchemaNs
)))
) {
8372 item->selector = xmlSchemaParseIDCSelectorAndField(ctxt,
8373 item, child, 0);
8374 child = child->next;
8375 /*
8376 * Child elements <field>.
8377 */
8378 if (IS_SCHEMA(child, "field")((child != ((void*)0)) && (child->ns != ((void*)0)
) && (xmlStrEqual(child->name, (const xmlChar *) "field"
)) && (xmlStrEqual(child->ns->href, xmlSchemaNs
)))
) {
8379 do {
8380 field = xmlSchemaParseIDCSelectorAndField(ctxt,
8381 item, child, 1);
8382 if (field != NULL((void*)0)) {
8383 field->index = item->nbFields;
8384 item->nbFields++;
8385 if (lastField != NULL((void*)0))
8386 lastField->next = field;
8387 else
8388 item->fields = field;
8389 lastField = field;
8390 }
8391 child = child->next;
8392 } while (IS_SCHEMA(child, "field")((child != ((void*)0)) && (child->ns != ((void*)0)
) && (xmlStrEqual(child->name, (const xmlChar *) "field"
)) && (xmlStrEqual(child->ns->href, xmlSchemaNs
)))
);
8393 } else {
8394 xmlSchemaPContentErr(ctxt,
8395 XML_SCHEMAP_S4S_ELEM_NOT_ALLOWED,
8396 NULL((void*)0), node, child,
8397 NULL((void*)0), "(annotation?, (selector, field+))");
8398 }
8399 }
8400 if (child != NULL((void*)0)) {
8401 xmlSchemaPContentErr(ctxt,
8402 XML_SCHEMAP_S4S_ELEM_NOT_ALLOWED,
8403 NULL((void*)0), node, child,
8404 NULL((void*)0), "(annotation?, (selector, field+))");
8405 }
8406
8407 return (item);
8408}
8409
8410/**
8411 * xmlSchemaParseElement:
8412 * @ctxt: a schema validation context
8413 * @schema: the schema being built
8414 * @node: a subtree containing XML Schema information
8415 * @topLevel: indicates if this is global declaration
8416 *
8417 * Parses a XML schema element declaration.
8418 * *WARNING* this interface is highly subject to change
8419 *
8420 * Returns the element declaration or a particle; NULL in case
8421 * of an error or if the particle has minOccurs==maxOccurs==0.
8422 */
8423static xmlSchemaBasicItemPtr
8424xmlSchemaParseElement(xmlSchemaParserCtxtPtr ctxt, xmlSchemaPtr schema,
8425 xmlNodePtr node, int *isElemRef, int topLevel)
8426{
8427 xmlSchemaElementPtr decl = NULL((void*)0);
8428 xmlSchemaParticlePtr particle = NULL((void*)0);
8429 xmlSchemaAnnotPtr annot = NULL((void*)0);
8430 xmlNodePtr child = NULL((void*)0);
8431 xmlAttrPtr attr, nameAttr;
8432 int min, max, isRef = 0;
8433 xmlChar *des = NULL((void*)0);
8434
8435 /* 3.3.3 Constraints on XML Representations of Element Declarations */
8436 /* TODO: Complete implementation of 3.3.6 */
8437
8438 if ((ctxt == NULL((void*)0)) || (schema == NULL((void*)0)) || (node == NULL((void*)0)))
8439 return (NULL((void*)0));
8440
8441 if (isElemRef != NULL((void*)0))
8442 *isElemRef = 0;
8443 /*
8444 * If we get a "ref" attribute on a local <element> we will assume it's
8445 * a reference - even if there's a "name" attribute; this seems to be more
8446 * robust.
8447 */
8448 nameAttr = xmlSchemaGetPropNode(node, "name");
8449 attr = xmlSchemaGetPropNode(node, "ref");
8450 if ((topLevel) || (attr == NULL((void*)0))) {
8451 if (nameAttr == NULL((void*)0)) {
8452 xmlSchemaPMissingAttrErr(ctxt,
8453 XML_SCHEMAP_S4S_ATTR_MISSING,
8454 NULL((void*)0), node, "name", NULL((void*)0));
8455 return (NULL((void*)0));
8456 }
8457 } else
8458 isRef = 1;
8459
8460 xmlSchemaPValAttrID(ctxt, node, BAD_CAST(xmlChar *) "id");
8461 child = node->children;
8462 if (IS_SCHEMA(child, "annotation")((child != ((void*)0)) && (child->ns != ((void*)0)
) && (xmlStrEqual(child->name, (const xmlChar *) "annotation"
)) && (xmlStrEqual(child->ns->href, xmlSchemaNs
)))
) {
8463 annot = xmlSchemaParseAnnotation(ctxt, child, 1);
8464 child = child->next;
8465 }
8466 /*
8467 * Skip particle part if a global declaration.
8468 */
8469 if (topLevel)
8470 goto declaration_part;
8471 /*
8472 * The particle part ==================================================
8473 */
8474 min = xmlGetMinOccurs(ctxt, node, 0, -1, 1, "xs:nonNegativeInteger");
8475 max = xmlGetMaxOccurs(ctxt, node, 0, UNBOUNDED(1 << 30), 1, "(xs:nonNegativeInteger | unbounded)");
8476 xmlSchemaPCheckParticleCorrect_2(ctxt, NULL((void*)0), node, min, max);
8477 particle = xmlSchemaAddParticle(ctxt, node, min, max);
8478 if (particle == NULL((void*)0))
8479 goto return_null;
8480
8481 /* ret->flags |= XML_SCHEMAS_ELEM_REF; */
8482
8483 if (isRef) {
8484 const xmlChar *refNs = NULL((void*)0), *ref = NULL((void*)0);
8485 xmlSchemaQNameRefPtr refer = NULL((void*)0);
8486 /*
8487 * The reference part =============================================
8488 */
8489 if (isElemRef != NULL((void*)0))
8490 *isElemRef = 1;
8491
8492 xmlSchemaPValAttrNodeQName(ctxt, schema,
8493 NULL((void*)0), attr, &refNs, &ref);
8494 xmlSchemaCheckReference(ctxt, schema, node, attr, refNs);
8495 /*
8496 * SPEC (3.3.3 : 2.1) "One of ref or name must be present, but not both"
8497 */
8498 if (nameAttr != NULL((void*)0)) {
8499 xmlSchemaPMutualExclAttrErr(ctxt,
8500 XML_SCHEMAP_SRC_ELEMENT_2_1, NULL((void*)0), nameAttr, "ref", "name");
8501 }
8502 /*
8503 * Check for illegal attributes.
8504 */
8505 attr = node->properties;
8506 while (attr != NULL((void*)0)) {
8507 if (attr->ns == NULL((void*)0)) {
8508 if (xmlStrEqual(attr->name, BAD_CAST(xmlChar *) "ref") ||
8509 xmlStrEqual(attr->name, BAD_CAST(xmlChar *) "name") ||
8510 xmlStrEqual(attr->name, BAD_CAST(xmlChar *) "id") ||
8511 xmlStrEqual(attr->name, BAD_CAST(xmlChar *) "maxOccurs") ||
8512 xmlStrEqual(attr->name, BAD_CAST(xmlChar *) "minOccurs"))
8513 {
8514 attr = attr->next;
8515 continue;
8516 } else {
8517 /* SPEC (3.3.3 : 2.2) */
8518 xmlSchemaPCustomAttrErr(ctxt,
8519 XML_SCHEMAP_SRC_ELEMENT_2_2,
8520 NULL((void*)0), NULL((void*)0), attr,
8521 "Only the attributes 'minOccurs', 'maxOccurs' and "
8522 "'id' are allowed in addition to 'ref'");
8523 break;
8524 }
8525 } else if (xmlStrEqual(attr->ns->href, xmlSchemaNs)) {
8526 xmlSchemaPIllegalAttrErr(ctxt,
8527 XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL((void*)0), attr);
8528 }
8529 attr = attr->next;
8530 }
8531 /*
8532 * No children except <annotation> expected.
8533 */
8534 if (child != NULL((void*)0)) {
8535 xmlSchemaPContentErr(ctxt, XML_SCHEMAP_S4S_ELEM_NOT_ALLOWED,
8536 NULL((void*)0), node, child, NULL((void*)0), "(annotation?)");
8537 }
8538 if ((min == 0) && (max == 0))
8539 goto return_null;
8540 /*
8541 * Create the reference item and attach it to the particle.
8542 */
8543 refer = xmlSchemaNewQNameRef(ctxt, XML_SCHEMA_TYPE_ELEMENT,
8544 ref, refNs);
8545 if (refer == NULL((void*)0))
8546 goto return_null;
8547 particle->children = (xmlSchemaTreeItemPtr) refer;
8548 particle->annot = annot;
8549 /*
8550 * Add the particle to pending components, since the reference
8551 * need to be resolved.
8552 */
8553 WXS_ADD_PENDING(ctxt, particle)xmlSchemaAddItemSize(&((ctxt)->constructor->pending
), 10, particle)
;
8554 return ((xmlSchemaBasicItemPtr) particle);
8555 }
8556 /*
8557 * The declaration part ===============================================
8558 */
8559declaration_part:
8560 {
8561 const xmlChar *ns = NULL((void*)0), *fixed, *name, *attrValue;
8562 xmlSchemaIDCPtr curIDC = NULL((void*)0), lastIDC = NULL((void*)0);
8563
8564 if (xmlSchemaPValAttrNode(ctxt, NULL((void*)0), nameAttr,
8565 xmlSchemaGetBuiltInType(XML_SCHEMAS_NCNAME), &name) != 0)
8566 goto return_null;
8567 /*
8568 * Evaluate the target namespace.
8569 */
8570 if (topLevel) {
8571 ns = ctxt->targetNamespace;
8572 } else {
8573 attr = xmlSchemaGetPropNode(node, "form");
8574 if (attr != NULL((void*)0)) {
8575 attrValue = xmlSchemaGetNodeContent(ctxt, (xmlNodePtr) attr);
8576 if (xmlStrEqual(attrValue, BAD_CAST(xmlChar *) "qualified")) {
8577 ns = ctxt->targetNamespace;
8578 } else if (!xmlStrEqual(attrValue, BAD_CAST(xmlChar *) "unqualified")) {
8579 xmlSchemaPSimpleTypeErr(ctxt,
8580 XML_SCHEMAP_S4S_ATTR_INVALID_VALUE,
8581 NULL((void*)0), (xmlNodePtr) attr,
8582 NULL((void*)0), "(qualified | unqualified)",
8583 attrValue, NULL((void*)0), NULL((void*)0), NULL((void*)0));
8584 }
8585 } else if (schema->flags & XML_SCHEMAS_QUALIF_ELEM1 << 0)
8586 ns = ctxt->targetNamespace;
8587 }
8588 decl = xmlSchemaAddElement(ctxt, name, ns, node, topLevel);
8589 if (decl == NULL((void*)0)) {
8590 goto return_null;
8591 }
8592 /*
8593 * Check for illegal attributes.
8594 */
8595 attr = node->properties;
8596 while (attr != NULL((void*)0)) {
8597 if (attr->ns == NULL((void*)0)) {
8598 if ((!xmlStrEqual(attr->name, BAD_CAST(xmlChar *) "name")) &&
8599 (!xmlStrEqual(attr->name, BAD_CAST(xmlChar *) "type")) &&
8600 (!xmlStrEqual(attr->name, BAD_CAST(xmlChar *) "id")) &&
8601 (!xmlStrEqual(attr->name, BAD_CAST(xmlChar *) "default")) &&
8602 (!xmlStrEqual(attr->name, BAD_CAST(xmlChar *) "fixed")) &&
8603 (!xmlStrEqual(attr->name, BAD_CAST(xmlChar *) "block")) &&
8604 (!xmlStrEqual(attr->name, BAD_CAST(xmlChar *) "nillable")))
8605 {
8606 if (topLevel == 0) {
8607 if ((!xmlStrEqual(attr->name, BAD_CAST(xmlChar *) "maxOccurs")) &&
8608 (!xmlStrEqual(attr->name, BAD_CAST(xmlChar *) "minOccurs")) &&
8609 (!xmlStrEqual(attr->name, BAD_CAST(xmlChar *) "form")))
8610 {
8611 xmlSchemaPIllegalAttrErr(ctxt,
8612 XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL((void*)0), attr);
8613 }
8614 } else if ((!xmlStrEqual(attr->name, BAD_CAST(xmlChar *) "final")) &&
8615 (!xmlStrEqual(attr->name, BAD_CAST(xmlChar *) "abstract")) &&
8616 (!xmlStrEqual(attr->name, BAD_CAST(xmlChar *) "substitutionGroup"))) {
8617
8618 xmlSchemaPIllegalAttrErr(ctxt,
8619 XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL((void*)0), attr);
8620 }
8621 }
8622 } else if (xmlStrEqual(attr->ns->href, xmlSchemaNs)) {
8623
8624 xmlSchemaPIllegalAttrErr(ctxt,
8625 XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL((void*)0), attr);
8626 }
8627 attr = attr->next;
8628 }
8629 /*
8630 * Extract/validate attributes.
8631 */
8632 if (topLevel) {
8633 /*
8634 * Process top attributes of global element declarations here.
8635 */
8636 decl->flags |= XML_SCHEMAS_ELEM_GLOBAL1 << 1;
8637 decl->flags |= XML_SCHEMAS_ELEM_TOPLEVEL1 << 5;
8638 xmlSchemaPValAttrQName(ctxt, schema,
8639 NULL((void*)0), node, "substitutionGroup",
8640 &(decl->substGroupNs), &(decl->substGroup));
8641 if (xmlGetBooleanProp(ctxt, node, "abstract", 0))
8642 decl->flags |= XML_SCHEMAS_ELEM_ABSTRACT1 << 4;
8643 /*
8644 * Attribute "final".
8645 */
8646 attr = xmlSchemaGetPropNode(node, "final");
8647 if (attr == NULL((void*)0)) {
8648 if (schema->flags & XML_SCHEMAS_FINAL_DEFAULT_EXTENSION1 << 2)
8649 decl->flags |= XML_SCHEMAS_ELEM_FINAL_EXTENSION1 << 15;
8650 if (schema->flags & XML_SCHEMAS_FINAL_DEFAULT_RESTRICTION1 << 3)
8651 decl->flags |= XML_SCHEMAS_ELEM_FINAL_RESTRICTION1 << 16;
8652 } else {
8653 attrValue = xmlSchemaGetNodeContent(ctxt, (xmlNodePtr) attr);
8654 if (xmlSchemaPValAttrBlockFinal(attrValue, &(decl->flags),
8655 -1,
8656 XML_SCHEMAS_ELEM_FINAL_EXTENSION1 << 15,
8657 XML_SCHEMAS_ELEM_FINAL_RESTRICTION1 << 16, -1, -1, -1) != 0) {
8658 xmlSchemaPSimpleTypeErr(ctxt,
8659 XML_SCHEMAP_S4S_ATTR_INVALID_VALUE,
8660 NULL((void*)0), (xmlNodePtr) attr,
8661 NULL((void*)0), "(#all | List of (extension | restriction))",
8662 attrValue, NULL((void*)0), NULL((void*)0), NULL((void*)0));
8663 }
8664 }
8665 }
8666 /*
8667 * Attribute "block".
8668 */
8669 attr = xmlSchemaGetPropNode(node, "block");
8670 if (attr == NULL((void*)0)) {
8671 /*
8672 * Apply default "block" values.
8673 */
8674 if (schema->flags & XML_SCHEMAS_BLOCK_DEFAULT_RESTRICTION1 << 7)
8675 decl->flags |= XML_SCHEMAS_ELEM_BLOCK_RESTRICTION1 << 12;
8676 if (schema->flags & XML_SCHEMAS_BLOCK_DEFAULT_EXTENSION1 << 6)
8677 decl->flags |= XML_SCHEMAS_ELEM_BLOCK_EXTENSION1 << 11;
8678 if (schema->flags & XML_SCHEMAS_BLOCK_DEFAULT_SUBSTITUTION1 << 8)
8679 decl->flags |= XML_SCHEMAS_ELEM_BLOCK_SUBSTITUTION1 << 13;
8680 } else {
8681 attrValue = xmlSchemaGetNodeContent(ctxt, (xmlNodePtr) attr);
8682 if (xmlSchemaPValAttrBlockFinal(attrValue, &(decl->flags),
8683 -1,
8684 XML_SCHEMAS_ELEM_BLOCK_EXTENSION1 << 11,
8685 XML_SCHEMAS_ELEM_BLOCK_RESTRICTION1 << 12,
8686 XML_SCHEMAS_ELEM_BLOCK_SUBSTITUTION1 << 13, -1, -1) != 0) {
8687 xmlSchemaPSimpleTypeErr(ctxt,
8688 XML_SCHEMAP_S4S_ATTR_INVALID_VALUE,
8689 NULL((void*)0), (xmlNodePtr) attr,
8690 NULL((void*)0), "(#all | List of (extension | "
8691 "restriction | substitution))", attrValue,
8692 NULL((void*)0), NULL((void*)0), NULL((void*)0));
8693 }
8694 }
8695 if (xmlGetBooleanProp(ctxt, node, "nillable", 0))
8696 decl->flags |= XML_SCHEMAS_ELEM_NILLABLE1 << 0;
8697
8698 attr = xmlSchemaGetPropNode(node, "type");
8699 if (attr != NULL((void*)0)) {
8700 xmlSchemaPValAttrNodeQName(ctxt, schema,
8701 NULL((void*)0), attr,
8702 &(decl->namedTypeNs), &(decl->namedType));
8703 xmlSchemaCheckReference(ctxt, schema, node,
8704 attr, decl->namedTypeNs);
8705 }
8706 decl->value = xmlSchemaGetProp(ctxt, node, "default");
8707 attr = xmlSchemaGetPropNode(node, "fixed");
8708 if (attr != NULL((void*)0)) {
8709 fixed = xmlSchemaGetNodeContent(ctxt, (xmlNodePtr) attr);
8710 if (decl->value != NULL((void*)0)) {
8711 /*
8712 * 3.3.3 : 1
8713 * default and fixed must not both be present.
8714 */
8715 xmlSchemaPMutualExclAttrErr(ctxt,
8716 XML_SCHEMAP_SRC_ELEMENT_1,
8717 NULL((void*)0), attr, "default", "fixed");
8718 } else {
8719 decl->flags |= XML_SCHEMAS_ELEM_FIXED1 << 3;
8720 decl->value = fixed;
8721 }
8722 }
8723 /*
8724 * And now for the children...
8725 */
8726 if (IS_SCHEMA(child, "complexType")((child != ((void*)0)) && (child->ns != ((void*)0)
) && (xmlStrEqual(child->name, (const xmlChar *) "complexType"
)) && (xmlStrEqual(child->ns->href, xmlSchemaNs
)))
) {
8727 /*
8728 * 3.3.3 : 3
8729 * "type" and either <simpleType> or <complexType> are mutually
8730 * exclusive
8731 */
8732 if (decl->namedType != NULL((void*)0)) {
8733 xmlSchemaPContentErr(ctxt,
8734 XML_SCHEMAP_SRC_ELEMENT_3,
8735 NULL((void*)0), node, child,
8736 "The attribute 'type' and the <complexType> child are "
8737 "mutually exclusive", NULL((void*)0));
8738 } else
8739 WXS_ELEM_TYPEDEF(decl)(decl)->subtypes = xmlSchemaParseComplexType(ctxt, schema, child, 0);
8740 child = child->next;
8741 } else if (IS_SCHEMA(child, "simpleType")((child != ((void*)0)) && (child->ns != ((void*)0)
) && (xmlStrEqual(child->name, (const xmlChar *) "simpleType"
)) && (xmlStrEqual(child->ns->href, xmlSchemaNs
)))
) {
8742 /*
8743 * 3.3.3 : 3
8744 * "type" and either <simpleType> or <complexType> are
8745 * mutually exclusive
8746 */
8747 if (decl->namedType != NULL((void*)0)) {
8748 xmlSchemaPContentErr(ctxt,
8749 XML_SCHEMAP_SRC_ELEMENT_3,
8750 NULL((void*)0), node, child,
8751 "The attribute 'type' and the <simpleType> child are "
8752 "mutually exclusive", NULL((void*)0));
8753 } else
8754 WXS_ELEM_TYPEDEF(decl)(decl)->subtypes = xmlSchemaParseSimpleType(ctxt, schema, child, 0);
8755 child = child->next;
8756 }
8757 while ((IS_SCHEMA(child, "unique")((child != ((void*)0)) && (child->ns != ((void*)0)
) && (xmlStrEqual(child->name, (const xmlChar *) "unique"
)) && (xmlStrEqual(child->ns->href, xmlSchemaNs
)))
) ||
8758 (IS_SCHEMA(child, "key")((child != ((void*)0)) && (child->ns != ((void*)0)
) && (xmlStrEqual(child->name, (const xmlChar *) "key"
)) && (xmlStrEqual(child->ns->href, xmlSchemaNs
)))
) || (IS_SCHEMA(child, "keyref")((child != ((void*)0)) && (child->ns != ((void*)0)
) && (xmlStrEqual(child->name, (const xmlChar *) "keyref"
)) && (xmlStrEqual(child->ns->href, xmlSchemaNs
)))
)) {
8759 if (IS_SCHEMA(child, "unique")((child != ((void*)0)) && (child->ns != ((void*)0)
) && (xmlStrEqual(child->name, (const xmlChar *) "unique"
)) && (xmlStrEqual(child->ns->href, xmlSchemaNs
)))
) {
8760 curIDC = xmlSchemaParseIDC(ctxt, schema, child,
8761 XML_SCHEMA_TYPE_IDC_UNIQUE, decl->targetNamespace);
8762 } else if (IS_SCHEMA(child, "key")((child != ((void*)0)) && (child->ns != ((void*)0)
) && (xmlStrEqual(child->name, (const xmlChar *) "key"
)) && (xmlStrEqual(child->ns->href, xmlSchemaNs
)))
) {
8763 curIDC = xmlSchemaParseIDC(ctxt, schema, child,
8764 XML_SCHEMA_TYPE_IDC_KEY, decl->targetNamespace);
8765 } else if (IS_SCHEMA(child, "keyref")((child != ((void*)0)) && (child->ns != ((void*)0)
) && (xmlStrEqual(child->name, (const xmlChar *) "keyref"
)) && (xmlStrEqual(child->ns->href, xmlSchemaNs
)))
) {
8766 curIDC = xmlSchemaParseIDC(ctxt, schema, child,
8767 XML_SCHEMA_TYPE_IDC_KEYREF, decl->targetNamespace);
8768 }
8769 if (lastIDC != NULL((void*)0))
8770 lastIDC->next = curIDC;
8771 else
8772 decl->idcs = (void *) curIDC;
8773 lastIDC = curIDC;
8774 child = child->next;
8775 }
8776 if (child != NULL((void*)0)) {
8777 xmlSchemaPContentErr(ctxt,
8778 XML_SCHEMAP_S4S_ELEM_NOT_ALLOWED,
8779 NULL((void*)0), node, child,
8780 NULL((void*)0), "(annotation?, ((simpleType | complexType)?, "
8781 "(unique | key | keyref)*))");
8782 }
8783 decl->annot = annot;
8784 }
8785 /*
8786 * NOTE: Element Declaration Representation OK 4. will be checked at a
8787 * different layer.
8788 */
8789 FREE_AND_NULL(des)if ((des) != ((void*)0)) { xmlFree((xmlChar *) (des)); des = (
(void*)0); }
8790 if (topLevel)
8791 return ((xmlSchemaBasicItemPtr) decl);
8792 else {
8793 particle->children = (xmlSchemaTreeItemPtr) decl;
8794 return ((xmlSchemaBasicItemPtr) particle);
8795 }
8796
8797return_null:
8798 FREE_AND_NULL(des)if ((des) != ((void*)0)) { xmlFree((xmlChar *) (des)); des = (
(void*)0); }
;
8799 if (annot != NULL((void*)0)) {
8800 if (particle != NULL((void*)0))
8801 particle->annot = NULL((void*)0);
8802 if (decl != NULL((void*)0))
8803 decl->annot = NULL((void*)0);
8804 xmlSchemaFreeAnnot(annot);
8805 }
8806 return (NULL((void*)0));
8807}
8808
8809/**
8810 * xmlSchemaParseUnion:
8811 * @ctxt: a schema validation context
8812 * @schema: the schema being built
8813 * @node: a subtree containing XML Schema information
8814 *
8815 * parse a XML schema Union definition
8816 * *WARNING* this interface is highly subject to change
8817 *
8818 * Returns -1 in case of internal error, 0 in case of success and a positive
8819 * error code otherwise.
8820 */
8821static int
8822xmlSchemaParseUnion(xmlSchemaParserCtxtPtr ctxt, xmlSchemaPtr schema,
8823 xmlNodePtr node)
8824{
8825 xmlSchemaTypePtr type;
8826 xmlNodePtr child = NULL((void*)0);
8827 xmlAttrPtr attr;
8828 const xmlChar *cur = NULL((void*)0);
8829
8830 if ((ctxt == NULL((void*)0)) || (schema == NULL((void*)0)) || (node == NULL((void*)0)))
8831 return (-1);
8832 /* Not a component, don't create it. */
8833 type = ctxt->ctxtType;
8834 /*
8835 * Mark the simple type as being of variety "union".
8836 */
8837 type->flags |= XML_SCHEMAS_TYPE_VARIETY_UNION1 << 7;
8838 /*
8839 * SPEC (Base type) (2) "If the <list> or <union> alternative is chosen,
8840 * then the `simple ur-type definition`."
8841 */
8842 type->baseType = xmlSchemaGetBuiltInType(XML_SCHEMAS_ANYSIMPLETYPE);
8843 /*
8844 * Check for illegal attributes.
8845 */
8846 attr = node->properties;
8847 while (attr != NULL((void*)0)) {
8848 if (attr->ns == NULL((void*)0)) {
8849 if ((!xmlStrEqual(attr->name, BAD_CAST(xmlChar *) "id")) &&
8850 (!xmlStrEqual(attr->name, BAD_CAST(xmlChar *) "memberTypes"))) {
8851 xmlSchemaPIllegalAttrErr(ctxt,
8852 XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL((void*)0), attr);
8853 }
8854 } else if (xmlStrEqual(attr->ns->href, xmlSchemaNs)) {
8855 xmlSchemaPIllegalAttrErr(ctxt,
8856 XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL((void*)0), attr);
8857 }
8858 attr = attr->next;
8859 }
8860 xmlSchemaPValAttrID(ctxt, node, BAD_CAST(xmlChar *) "id");
8861 /*
8862 * Attribute "memberTypes". This is a list of QNames.
8863 * TODO: Check the value to contain anything.
8864 */
8865 attr = xmlSchemaGetPropNode(node, "memberTypes");
8866 if (attr != NULL((void*)0)) {
8867 const xmlChar *end;
8868 xmlChar *tmp;
8869 const xmlChar *localName, *nsName;
8870 xmlSchemaTypeLinkPtr link, lastLink = NULL((void*)0);
8871 xmlSchemaQNameRefPtr ref;
8872
8873 cur = xmlSchemaGetNodeContent(ctxt, (xmlNodePtr) attr);
8874 if (cur == NULL((void*)0))
8875 return (-1);
8876 type->base = cur;
8877 do {
8878 while (IS_BLANK_CH(*cur)(((*cur) == 0x20) || ((0x9 <= (*cur)) && ((*cur) <=
0xa)) || ((*cur) == 0xd))
)
8879 cur++;
8880 end = cur;
8881 while ((*end != 0) && (!(IS_BLANK_CH(*end)(((*end) == 0x20) || ((0x9 <= (*end)) && ((*end) <=
0xa)) || ((*end) == 0xd))
)))
8882 end++;
8883 if (end == cur)
8884 break;
8885 tmp = xmlStrndup(cur, end - cur);
8886 if (tmp == NULL((void*)0)) {
8887 xmlSchemaPErrMemory(ctxt, "xmlSchemaParseUnion, "
8888 "duplicating type name", NULL((void*)0));
8889 return (-1);
8890 }
8891 if (xmlSchemaPValAttrNodeQNameValue(ctxt, schema,
8892 NULL((void*)0), attr, BAD_CAST(xmlChar *) tmp, &nsName, &localName) == 0) {
8893 /*
8894 * Create the member type link.
8895 */
8896 link = (xmlSchemaTypeLinkPtr)
8897 xmlMalloc(sizeof(xmlSchemaTypeLink));
8898 if (link == NULL((void*)0)) {
8899 xmlSchemaPErrMemory(ctxt, "xmlSchemaParseUnion, "
8900 "allocating a type link", NULL((void*)0));
8901 FREE_AND_NULL(tmp)if ((tmp) != ((void*)0)) { xmlFree((xmlChar *) (tmp)); tmp = (
(void*)0); }
8902 return (-1);
8903 }
8904 link->type = NULL((void*)0);
8905 link->next = NULL((void*)0);
8906 if (lastLink == NULL((void*)0))
8907 type->memberTypes = link;
8908 else
8909 lastLink->next = link;
8910 lastLink = link;
8911 /*
8912 * Create a reference item.
8913 */
8914 ref = xmlSchemaNewQNameRef(ctxt, XML_SCHEMA_TYPE_SIMPLE,
8915 localName, nsName);
8916 if (ref == NULL((void*)0)) {
8917 FREE_AND_NULL(tmp)if ((tmp) != ((void*)0)) { xmlFree((xmlChar *) (tmp)); tmp = (
(void*)0); }
8918 return (-1);
8919 }
8920 /*
8921 * Assign the reference to the link, it will be resolved
8922 * later during fixup of the union simple type.
8923 */
8924 link->type = (xmlSchemaTypePtr) ref;
8925 }
8926 FREE_AND_NULL(tmp)if ((tmp) != ((void*)0)) { xmlFree((xmlChar *) (tmp)); tmp = (
(void*)0); }
8927 cur = end;
8928 } while (*cur != 0);
8929
8930 }
8931 /*
8932 * And now for the children...
8933 */
8934 child = node->children;
8935 if (IS_SCHEMA(child, "annotation")((child != ((void*)0)) && (child->ns != ((void*)0)
) && (xmlStrEqual(child->name, (const xmlChar *) "annotation"
)) && (xmlStrEqual(child->ns->href, xmlSchemaNs
)))
) {
8936 /*
8937 * Add the annotation to the simple type ancestor.
8938 */
8939 xmlSchemaAddAnnotation((xmlSchemaAnnotItemPtr) type,
8940 xmlSchemaParseAnnotation(ctxt, child, 1));
8941 child = child->next;
8942 }
8943 if (IS_SCHEMA(child, "simpleType")((child != ((void*)0)) && (child->ns != ((void*)0)
) && (xmlStrEqual(child->name, (const xmlChar *) "simpleType"
)) && (xmlStrEqual(child->ns->href, xmlSchemaNs
)))
) {
8944 xmlSchemaTypePtr subtype, last = NULL((void*)0);
8945
8946 /*
8947 * Anchor the member types in the "subtypes" field of the
8948 * simple type.
8949 */
8950 while (IS_SCHEMA(child, "simpleType")((child != ((void*)0)) && (child->ns != ((void*)0)
) && (xmlStrEqual(child->name, (const xmlChar *) "simpleType"
)) && (xmlStrEqual(child->ns->href, xmlSchemaNs
)))
) {
8951 subtype = (xmlSchemaTypePtr)
8952 xmlSchemaParseSimpleType(ctxt, schema, child, 0);
8953 if (subtype != NULL((void*)0)) {
8954 if (last == NULL((void*)0)) {
8955 type->subtypes = subtype;
8956 last = subtype;
8957 } else {
8958 last->next = subtype;
8959 last = subtype;
8960 }
8961 last->next = NULL((void*)0);
8962 }
8963 child = child->next;
8964 }
8965 }
8966 if (child != NULL((void*)0)) {
8967 xmlSchemaPContentErr(ctxt,
8968 XML_SCHEMAP_S4S_ELEM_NOT_ALLOWED,
8969 NULL((void*)0), node, child, NULL((void*)0), "(annotation?, simpleType*)");
8970 }
8971 if ((attr == NULL((void*)0)) && (type->subtypes == NULL((void*)0))) {
8972 /*
8973 * src-union-memberTypes-or-simpleTypes
8974 * Either the memberTypes [attribute] of the <union> element must
8975 * be non-empty or there must be at least one simpleType [child].
8976 */
8977 xmlSchemaPCustomErr(ctxt,
8978 XML_SCHEMAP_SRC_UNION_MEMBERTYPES_OR_SIMPLETYPES,
8979 NULL((void*)0), node,
8980 "Either the attribute 'memberTypes' or "
8981 "at least one <simpleType> child must be present", NULL((void*)0));
8982 }
8983 return (0);
8984}
8985
8986/**
8987 * xmlSchemaParseList:
8988 * @ctxt: a schema validation context
8989 * @schema: the schema being built
8990 * @node: a subtree containing XML Schema information
8991 *
8992 * parse a XML schema List definition
8993 * *WARNING* this interface is highly subject to change
8994 *
8995 * Returns -1 in case of error, 0 if the declaration is improper and
8996 * 1 in case of success.
8997 */
8998static xmlSchemaTypePtr
8999xmlSchemaParseList(xmlSchemaParserCtxtPtr ctxt, xmlSchemaPtr schema,
9000 xmlNodePtr node)
9001{
9002 xmlSchemaTypePtr type;
9003 xmlNodePtr child = NULL((void*)0);
9004 xmlAttrPtr attr;
9005
9006 if ((ctxt == NULL((void*)0)) || (schema == NULL((void*)0)) || (node == NULL((void*)0)))
9007 return (NULL((void*)0));
9008 /* Not a component, don't create it. */
9009 type = ctxt->ctxtType;
9010 /*
9011 * Mark the type as being of variety "list".
9012 */
9013 type->flags |= XML_SCHEMAS_TYPE_VARIETY_LIST1 << 6;
9014 /*
9015 * SPEC (Base type) (2) "If the <list> or <union> alternative is chosen,
9016 * then the `simple ur-type definition`."
9017 */
9018 type->baseType = xmlSchemaGetBuiltInType(XML_SCHEMAS_ANYSIMPLETYPE);
9019 /*
9020 * Check for illegal attributes.
9021 */
9022 attr = node->properties;
9023 while (attr != NULL((void*)0)) {
9024 if (attr->ns == NULL((void*)0)) {
9025 if ((!xmlStrEqual(attr->name, BAD_CAST(xmlChar *) "id")) &&
9026 (!xmlStrEqual(attr->name, BAD_CAST(xmlChar *) "itemType"))) {
9027 xmlSchemaPIllegalAttrErr(ctxt,
9028 XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL((void*)0), attr);
9029 }
9030 } else if (xmlStrEqual(attr->ns->href, xmlSchemaNs)) {
9031 xmlSchemaPIllegalAttrErr(ctxt,
9032 XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL((void*)0), attr);
9033 }
9034 attr = attr->next;
9035 }
9036
9037 xmlSchemaPValAttrID(ctxt, node, BAD_CAST(xmlChar *) "id");
9038
9039 /*
9040 * Attribute "itemType". NOTE that we will use the "ref" and "refNs"
9041 * fields for holding the reference to the itemType.
9042 *
9043 * REVAMP TODO: Use the "base" and "baseNs" fields, since we will remove
9044 * the "ref" fields.
9045 */
9046 xmlSchemaPValAttrQName(ctxt, schema, NULL((void*)0),
9047 node, "itemType", &(type->baseNs), &(type->base));
9048 /*
9049 * And now for the children...
9050 */
9051 child = node->children;
9052 if (IS_SCHEMA(child, "annotation")((child != ((void*)0)) && (child->ns != ((void*)0)
) && (xmlStrEqual(child->name, (const xmlChar *) "annotation"
)) && (xmlStrEqual(child->ns->href, xmlSchemaNs
)))
) {
9053 xmlSchemaAddAnnotation((xmlSchemaAnnotItemPtr) type,
9054 xmlSchemaParseAnnotation(ctxt, child, 1));
9055 child = child->next;
9056 }
9057 if (IS_SCHEMA(child, "simpleType")((child != ((void*)0)) && (child->ns != ((void*)0)
) && (xmlStrEqual(child->name, (const xmlChar *) "simpleType"
)) && (xmlStrEqual(child->ns->href, xmlSchemaNs
)))
) {
9058 /*
9059 * src-list-itemType-or-simpleType
9060 * Either the itemType [attribute] or the <simpleType> [child] of
9061 * the <list> element must be present, but not both.
9062 */
9063 if (type->base != NULL((void*)0)) {
9064 xmlSchemaPCustomErr(ctxt,
9065 XML_SCHEMAP_SRC_SIMPLE_TYPE_1,
9066 NULL((void*)0), node,
9067 "The attribute 'itemType' and the <simpleType> child "
9068 "are mutually exclusive", NULL((void*)0));
9069 } else {
9070 type->subtypes = xmlSchemaParseSimpleType(ctxt, schema, child, 0);
9071 }
9072 child = child->next;
9073 } else if (type->base == NULL((void*)0)) {
9074 xmlSchemaPCustomErr(ctxt,
9075 XML_SCHEMAP_SRC_SIMPLE_TYPE_1,
9076 NULL((void*)0), node,
9077 "Either the attribute 'itemType' or the <simpleType> child "
9078 "must be present", NULL((void*)0));
9079 }
9080 if (child != NULL((void*)0)) {
9081 xmlSchemaPContentErr(ctxt,
9082 XML_SCHEMAP_S4S_ELEM_NOT_ALLOWED,
9083 NULL((void*)0), node, child, NULL((void*)0), "(annotation?, simpleType?)");
9084 }
9085 if ((type->base == NULL((void*)0)) &&
9086 (type->subtypes == NULL((void*)0)) &&
9087 (xmlSchemaGetPropNode(node, "itemType") == NULL((void*)0))) {
9088 xmlSchemaPCustomErr(ctxt,
9089 XML_SCHEMAP_SRC_SIMPLE_TYPE_1,
9090 NULL((void*)0), node,
9091 "Either the attribute 'itemType' or the <simpleType> child "
9092 "must be present", NULL((void*)0));
9093 }
9094 return (NULL((void*)0));
9095}
9096
9097/**
9098 * xmlSchemaParseSimpleType:
9099 * @ctxt: a schema validation context
9100 * @schema: the schema being built
9101 * @node: a subtree containing XML Schema information
9102 *
9103 * parse a XML schema Simple Type definition
9104 * *WARNING* this interface is highly subject to change
9105 *
9106 * Returns -1 in case of error, 0 if the declaration is improper and
9107 * 1 in case of success.
9108 */
9109static xmlSchemaTypePtr
9110xmlSchemaParseSimpleType(xmlSchemaParserCtxtPtr ctxt, xmlSchemaPtr schema,
9111 xmlNodePtr node, int topLevel)
9112{
9113 xmlSchemaTypePtr type, oldCtxtType;
9114 xmlNodePtr child = NULL((void*)0);
9115 const xmlChar *attrValue = NULL((void*)0);
9116 xmlAttrPtr attr;
9117 int hasRestriction = 0;
9118
9119 if ((ctxt == NULL((void*)0)) || (schema == NULL((void*)0)) || (node == NULL((void*)0)))
9120 return (NULL((void*)0));
9121
9122 if (topLevel) {
9123 attr = xmlSchemaGetPropNode(node, "name");
9124 if (attr == NULL((void*)0)) {
9125 xmlSchemaPMissingAttrErr(ctxt,
9126 XML_SCHEMAP_S4S_ATTR_MISSING,
9127 NULL((void*)0), node,
9128 "name", NULL((void*)0));
9129 return (NULL((void*)0));
9130 } else {
9131 if (xmlSchemaPValAttrNode(ctxt,
9132 NULL((void*)0), attr,
9133 xmlSchemaGetBuiltInType(XML_SCHEMAS_NCNAME), &attrValue) != 0)
9134 return (NULL((void*)0));
9135 /*
9136 * Skip built-in types.
9137 */
9138 if (ctxt->isS4S) {
9139 xmlSchemaTypePtr biType;
9140
9141 if (ctxt->isRedefine) {
9142 /*
9143 * REDEFINE: Disallow redefinition of built-in-types.
9144 * TODO: It seems that the spec does not say anything
9145 * about this case.
9146 */
9147 xmlSchemaPCustomErr(ctxt, XML_SCHEMAP_SRC_REDEFINE,
9148 NULL((void*)0), node,
9149 "Redefinition of built-in simple types is not "
9150 "supported", NULL((void*)0));
9151 return(NULL((void*)0));
9152 }
9153 biType = xmlSchemaGetPredefinedType(attrValue, xmlSchemaNs);
9154 if (biType != NULL((void*)0))
9155 return (biType);
9156 }
9157 }
9158 }
9159 /*
9160 * TargetNamespace:
9161 * SPEC "The `actual value` of the targetNamespace [attribute]
9162 * of the <schema> ancestor element information item if present,
9163 * otherwise `absent`.
9164 */
9165 if (topLevel == 0) {
9166#ifdef ENABLE_NAMED_LOCALS
9167 char buf[40];
9168#endif
9169 /*
9170 * Parse as local simple type definition.
9171 */
9172#ifdef ENABLE_NAMED_LOCALS
9173 snprintf(buf, 39, "#ST%d", ctxt->counter++ + 1);
9174 type = xmlSchemaAddType(ctxt, schema,
9175 XML_SCHEMA_TYPE_SIMPLE,
9176 xmlDictLookup(ctxt->dict, (const xmlChar *)buf, -1),
9177 ctxt->targetNamespace, node, 0);
9178#else
9179 type = xmlSchemaAddType(ctxt, schema,
9180 XML_SCHEMA_TYPE_SIMPLE,
9181 NULL((void*)0), ctxt->targetNamespace, node, 0);
9182#endif
9183 if (type == NULL((void*)0))
9184 return (NULL((void*)0));
9185 type->type = XML_SCHEMA_TYPE_SIMPLE;
9186 type->contentType = XML_SCHEMA_CONTENT_SIMPLE;
9187 /*
9188 * Check for illegal attributes.
9189 */
9190 attr = node->properties;
9191 while (attr != NULL((void*)0)) {
9192 if (attr->ns == NULL((void*)0)) {
9193 if (!xmlStrEqual(attr->name, BAD_CAST(xmlChar *) "id")) {
9194 xmlSchemaPIllegalAttrErr(ctxt,
9195 XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL((void*)0), attr);
9196 }
9197 } else if (xmlStrEqual(attr->ns->href, xmlSchemaNs)) {
9198 xmlSchemaPIllegalAttrErr(ctxt,
9199 XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL((void*)0), attr);
9200 }
9201 attr = attr->next;
9202 }
9203 } else {
9204 /*
9205 * Parse as global simple type definition.
9206 *
9207 * Note that attrValue is the value of the attribute "name" here.
9208 */
9209 type = xmlSchemaAddType(ctxt, schema, XML_SCHEMA_TYPE_SIMPLE,
9210 attrValue, ctxt->targetNamespace, node, 1);
9211 if (type == NULL((void*)0))
9212 return (NULL((void*)0));
9213 type->type = XML_SCHEMA_TYPE_SIMPLE;
9214 type->contentType = XML_SCHEMA_CONTENT_SIMPLE;
9215 type->flags |= XML_SCHEMAS_TYPE_GLOBAL1 << 3;
9216 /*
9217 * Check for illegal attributes.
9218 */
9219 attr = node->properties;
9220 while (attr != NULL((void*)0)) {
9221 if (attr->ns == NULL((void*)0)) {
9222 if ((!xmlStrEqual(attr->name, BAD_CAST(xmlChar *) "id")) &&
9223 (!xmlStrEqual(attr->name, BAD_CAST(xmlChar *) "name")) &&
9224 (!xmlStrEqual(attr->name, BAD_CAST(xmlChar *) "final"))) {
9225 xmlSchemaPIllegalAttrErr(ctxt,
9226 XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL((void*)0), attr);
9227 }
9228 } else if (xmlStrEqual(attr->ns->href, xmlSchemaNs)) {
9229 xmlSchemaPIllegalAttrErr(ctxt,
9230 XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL((void*)0), attr);
9231 }
9232 attr = attr->next;
9233 }
9234 /*
9235 * Attribute "final".
9236 */
9237 attr = xmlSchemaGetPropNode(node, "final");
9238 if (attr == NULL((void*)0)) {
9239 if (schema->flags & XML_SCHEMAS_FINAL_DEFAULT_RESTRICTION1 << 3)
9240 type->flags |= XML_SCHEMAS_TYPE_FINAL_RESTRICTION1 << 10;
9241 if (schema->flags & XML_SCHEMAS_FINAL_DEFAULT_LIST1 << 4)
9242 type->flags |= XML_SCHEMAS_TYPE_FINAL_LIST1 << 11;
9243 if (schema->flags & XML_SCHEMAS_FINAL_DEFAULT_UNION1 << 5)
9244 type->flags |= XML_SCHEMAS_TYPE_FINAL_UNION1 << 12;
9245 } else {
9246 attrValue = xmlSchemaGetProp(ctxt, node, "final");
9247 if (xmlSchemaPValAttrBlockFinal(attrValue, &(type->flags),
9248 -1, -1, XML_SCHEMAS_TYPE_FINAL_RESTRICTION1 << 10, -1,
9249 XML_SCHEMAS_TYPE_FINAL_LIST1 << 11,
9250 XML_SCHEMAS_TYPE_FINAL_UNION1 << 12) != 0) {
9251
9252 xmlSchemaPSimpleTypeErr(ctxt,
9253 XML_SCHEMAP_S4S_ATTR_INVALID_VALUE,
9254 WXS_BASIC_CAST(xmlSchemaBasicItemPtr) type, (xmlNodePtr) attr,
9255 NULL((void*)0), "(#all | List of (list | union | restriction)",
9256 attrValue, NULL((void*)0), NULL((void*)0), NULL((void*)0));
9257 }
9258 }
9259 }
9260 type->targetNamespace = ctxt->targetNamespace;
9261 xmlSchemaPValAttrID(ctxt, node, BAD_CAST(xmlChar *) "id");
9262 /*
9263 * And now for the children...
9264 */
9265 oldCtxtType = ctxt->ctxtType;
9266
9267 ctxt->ctxtType = type;
9268
9269 child = node->children;
9270 if (IS_SCHEMA(child, "annotation")((child != ((void*)0)) && (child->ns != ((void*)0)
) && (xmlStrEqual(child->name, (const xmlChar *) "annotation"
)) && (xmlStrEqual(child->ns->href, xmlSchemaNs
)))
) {
9271 type->annot = xmlSchemaParseAnnotation(ctxt, child, 1);
9272 child = child->next;
9273 }
9274 if (child == NULL((void*)0)) {
9275 xmlSchemaPContentErr(ctxt, XML_SCHEMAP_S4S_ELEM_MISSING,
9276 NULL((void*)0), node, child, NULL((void*)0),
9277 "(annotation?, (restriction | list | union))");
9278 } else if (IS_SCHEMA(child, "restriction")((child != ((void*)0)) && (child->ns != ((void*)0)
) && (xmlStrEqual(child->name, (const xmlChar *) "restriction"
)) && (xmlStrEqual(child->ns->href, xmlSchemaNs
)))
) {
9279 xmlSchemaParseRestriction(ctxt, schema, child,
9280 XML_SCHEMA_TYPE_SIMPLE);
9281 hasRestriction = 1;
9282 child = child->next;
9283 } else if (IS_SCHEMA(child, "list")((child != ((void*)0)) && (child->ns != ((void*)0)
) && (xmlStrEqual(child->name, (const xmlChar *) "list"
)) && (xmlStrEqual(child->ns->href, xmlSchemaNs
)))
) {
9284 xmlSchemaParseList(ctxt, schema, child);
9285 child = child->next;
9286 } else if (IS_SCHEMA(child, "union")((child != ((void*)0)) && (child->ns != ((void*)0)
) && (xmlStrEqual(child->name, (const xmlChar *) "union"
)) && (xmlStrEqual(child->ns->href, xmlSchemaNs
)))
) {
9287 xmlSchemaParseUnion(ctxt, schema, child);
9288 child = child->next;
9289 }
9290 if (child != NULL((void*)0)) {
9291 xmlSchemaPContentErr(ctxt, XML_SCHEMAP_S4S_ELEM_NOT_ALLOWED,
9292 NULL((void*)0), node, child, NULL((void*)0),
9293 "(annotation?, (restriction | list | union))");
9294 }
9295 /*
9296 * REDEFINE: SPEC src-redefine (5)
9297 * "Within the [children], each <simpleType> must have a
9298 * <restriction> among its [children] ... the `actual value` of whose
9299 * base [attribute] must be the same as the `actual value` of its own
9300 * name attribute plus target namespace;"
9301 */
9302 if (topLevel && ctxt->isRedefine && (! hasRestriction)) {
9303 xmlSchemaPCustomErr(ctxt, XML_SCHEMAP_SRC_REDEFINE,
9304 NULL((void*)0), node, "This is a redefinition, thus the "
9305 "<simpleType> must have a <restriction> child", NULL((void*)0));
9306 }
9307
9308 ctxt->ctxtType = oldCtxtType;
9309 return (type);
9310}
9311
9312/**
9313 * xmlSchemaParseModelGroupDefRef:
9314 * @ctxt: the parser context
9315 * @schema: the schema being built
9316 * @node: the node
9317 *
9318 * Parses a reference to a model group definition.
9319 *
9320 * We will return a particle component with a qname-component or
9321 * NULL in case of an error.
9322 */
9323static xmlSchemaTreeItemPtr
9324xmlSchemaParseModelGroupDefRef(xmlSchemaParserCtxtPtr ctxt,
9325 xmlSchemaPtr schema,
9326 xmlNodePtr node)
9327{
9328 xmlSchemaParticlePtr item;
9329 xmlNodePtr child = NULL((void*)0);
9330 xmlAttrPtr attr;
9331 const xmlChar *ref = NULL((void*)0), *refNs = NULL((void*)0);
9332 int min, max;
9333
9334 if ((ctxt == NULL((void*)0)) || (schema == NULL((void*)0)) || (node == NULL((void*)0)))
9335 return (NULL((void*)0));
9336
9337 attr = xmlSchemaGetPropNode(node, "ref");
9338 if (attr == NULL((void*)0)) {
9339 xmlSchemaPMissingAttrErr(ctxt,
9340 XML_SCHEMAP_S4S_ATTR_MISSING,
9341 NULL((void*)0), node, "ref", NULL((void*)0));
9342 return (NULL((void*)0));
9343 } else if (xmlSchemaPValAttrNodeQName(ctxt, schema, NULL((void*)0),
9344 attr, &refNs, &ref) != 0) {
9345 return (NULL((void*)0));
9346 }
9347 xmlSchemaCheckReference(ctxt, schema, node, attr, refNs);
9348 min = xmlGetMinOccurs(ctxt, node, 0, -1, 1, "xs:nonNegativeInteger");
9349 max = xmlGetMaxOccurs(ctxt, node, 0, UNBOUNDED(1 << 30), 1,
9350 "(xs:nonNegativeInteger | unbounded)");
9351 /*
9352 * Check for illegal attributes.
9353 */
9354 attr = node->properties;
9355 while (attr != NULL((void*)0)) {
9356 if (attr->ns == NULL((void*)0)) {
9357 if ((!xmlStrEqual(attr->name, BAD_CAST(xmlChar *) "ref")) &&
9358 (!xmlStrEqual(attr->name, BAD_CAST(xmlChar *) "id")) &&
9359 (!xmlStrEqual(attr->name, BAD_CAST(xmlChar *) "minOccurs")) &&
9360 (!xmlStrEqual(attr->name, BAD_CAST(xmlChar *) "maxOccurs"))) {
9361 xmlSchemaPIllegalAttrErr(ctxt,
9362 XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL((void*)0), attr);
9363 }
9364 } else if (xmlStrEqual(attr->ns->href, xmlSchemaNs)) {
9365 xmlSchemaPIllegalAttrErr(ctxt,
9366 XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL((void*)0), attr);
9367 }
9368 attr = attr->next;
9369 }
9370 xmlSchemaPValAttrID(ctxt, node, BAD_CAST(xmlChar *) "id");
9371 item = xmlSchemaAddParticle(ctxt, node, min, max);
9372 if (item == NULL((void*)0))
9373 return (NULL((void*)0));
9374 /*
9375 * Create a qname-reference and set as the term; it will be substituted
9376 * for the model group after the reference has been resolved.
9377 */
9378 item->children = (xmlSchemaTreeItemPtr)
9379 xmlSchemaNewQNameRef(ctxt, XML_SCHEMA_TYPE_GROUP, ref, refNs);
9380 xmlSchemaPCheckParticleCorrect_2(ctxt, item, node, min, max);
9381 /*
9382 * And now for the children...
9383 */
9384 child = node->children;
9385 /* TODO: Is annotation even allowed for a model group reference? */
9386 if (IS_SCHEMA(child, "annotation")((child != ((void*)0)) && (child->ns != ((void*)0)
) && (xmlStrEqual(child->name, (const xmlChar *) "annotation"
)) && (xmlStrEqual(child->ns->href, xmlSchemaNs
)))
) {
9387 /*
9388 * TODO: What to do exactly with the annotation?
9389 */
9390 item->annot = xmlSchemaParseAnnotation(ctxt, child, 1);
9391 child = child->next;
9392 }
9393 if (child != NULL((void*)0)) {
9394 xmlSchemaPContentErr(ctxt,
9395 XML_SCHEMAP_S4S_ELEM_NOT_ALLOWED,
9396 NULL((void*)0), node, child, NULL((void*)0),
9397 "(annotation?)");
9398 }
9399 /*
9400 * Corresponds to no component at all if minOccurs==maxOccurs==0.
9401 */
9402 if ((min == 0) && (max == 0))
9403 return (NULL((void*)0));
9404
9405 return ((xmlSchemaTreeItemPtr) item);
9406}
9407
9408/**
9409 * xmlSchemaParseModelGroupDefinition:
9410 * @ctxt: a schema validation context
9411 * @schema: the schema being built
9412 * @node: a subtree containing XML Schema information
9413 *
9414 * Parses a XML schema model group definition.
9415 *
9416 * Note that the constraint src-redefine (6.2) can't be applied until
9417 * references have been resolved. So we will do this at the
9418 * component fixup level.
9419 *
9420 * *WARNING* this interface is highly subject to change
9421 *
9422 * Returns -1 in case of error, 0 if the declaration is improper and
9423 * 1 in case of success.
9424 */
9425static xmlSchemaModelGroupDefPtr
9426xmlSchemaParseModelGroupDefinition(xmlSchemaParserCtxtPtr ctxt,
9427 xmlSchemaPtr schema,
9428 xmlNodePtr node)
9429{
9430 xmlSchemaModelGroupDefPtr item;
9431 xmlNodePtr child = NULL((void*)0);
9432 xmlAttrPtr attr;
9433 const xmlChar *name;
9434
9435 if ((ctxt == NULL((void*)0)) || (schema == NULL((void*)0)) || (node == NULL((void*)0)))
9436 return (NULL((void*)0));
9437
9438 attr = xmlSchemaGetPropNode(node, "name");
9439 if (attr == NULL((void*)0)) {
9440 xmlSchemaPMissingAttrErr(ctxt,
9441 XML_SCHEMAP_S4S_ATTR_MISSING,
9442 NULL((void*)0), node,
9443 "name", NULL((void*)0));
9444 return (NULL((void*)0));
9445 } else if (xmlSchemaPValAttrNode(ctxt, NULL((void*)0), attr,
9446 xmlSchemaGetBuiltInType(XML_SCHEMAS_NCNAME), &name) != 0) {
9447 return (NULL((void*)0));
9448 }
9449 item = xmlSchemaAddModelGroupDefinition(ctxt, schema, name,
9450 ctxt->targetNamespace, node);
9451 if (item == NULL((void*)0))
9452 return (NULL((void*)0));
9453 /*
9454 * Check for illegal attributes.
9455 */
9456 attr = node->properties;
9457 while (attr != NULL((void*)0)) {
9458 if (attr->ns == NULL((void*)0)) {
9459 if ((!xmlStrEqual(attr->name, BAD_CAST(xmlChar *) "name")) &&
9460 (!xmlStrEqual(attr->name, BAD_CAST(xmlChar *) "id"))) {
9461 xmlSchemaPIllegalAttrErr(ctxt,
9462 XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL((void*)0), attr);
9463 }
9464 } else if (xmlStrEqual(attr->ns->href, xmlSchemaNs)) {
9465 xmlSchemaPIllegalAttrErr(ctxt,
9466 XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL((void*)0), attr);
9467 }
9468 attr = attr->next;
9469 }
9470 xmlSchemaPValAttrID(ctxt, node, BAD_CAST(xmlChar *) "id");
9471 /*
9472 * And now for the children...
9473 */
9474 child = node->children;
9475 if (IS_SCHEMA(child, "annotation")((child != ((void*)0)) && (child->ns != ((void*)0)
) && (xmlStrEqual(child->name, (const xmlChar *) "annotation"
)) && (xmlStrEqual(child->ns->href, xmlSchemaNs
)))
) {
9476 item->annot = xmlSchemaParseAnnotation(ctxt, child, 1);
9477 child = child->next;
9478 }
9479 if (IS_SCHEMA(child, "all")((child != ((void*)0)) && (child->ns != ((void*)0)
) && (xmlStrEqual(child->name, (const xmlChar *) "all"
)) && (xmlStrEqual(child->ns->href, xmlSchemaNs
)))
) {
9480 item->children = xmlSchemaParseModelGroup(ctxt, schema, child,
9481 XML_SCHEMA_TYPE_ALL, 0);
9482 child = child->next;
9483 } else if (IS_SCHEMA(child, "choice")((child != ((void*)0)) && (child->ns != ((void*)0)
) && (xmlStrEqual(child->name, (const xmlChar *) "choice"
)) && (xmlStrEqual(child->ns->href, xmlSchemaNs
)))
) {
9484 item->children = xmlSchemaParseModelGroup(ctxt, schema, child,
9485 XML_SCHEMA_TYPE_CHOICE, 0);
9486 child = child->next;
9487 } else if (IS_SCHEMA(child, "sequence")((child != ((void*)0)) && (child->ns != ((void*)0)
) && (xmlStrEqual(child->name, (const xmlChar *) "sequence"
)) && (xmlStrEqual(child->ns->href, xmlSchemaNs
)))
) {
9488 item->children = xmlSchemaParseModelGroup(ctxt, schema, child,
9489 XML_SCHEMA_TYPE_SEQUENCE, 0);
9490 child = child->next;
9491 }
9492
9493
9494
9495 if (child != NULL((void*)0)) {
9496 xmlSchemaPContentErr(ctxt,
9497 XML_SCHEMAP_S4S_ELEM_NOT_ALLOWED,
9498 NULL((void*)0), node, child, NULL((void*)0),
9499 "(annotation?, (all | choice | sequence)?)");
9500 }
9501 return (item);
9502}
9503
9504/**
9505 * xmlSchemaCleanupDoc:
9506 * @ctxt: a schema validation context
9507 * @node: the root of the document.
9508 *
9509 * removes unwanted nodes in a schemas document tree
9510 */
9511static void
9512xmlSchemaCleanupDoc(xmlSchemaParserCtxtPtr ctxt, xmlNodePtr root)
9513{
9514 xmlNodePtr delete, cur;
9515
9516 if ((ctxt == NULL((void*)0)) || (root == NULL((void*)0))) return;
9517
9518 /*
9519 * Remove all the blank text nodes
9520 */
9521 delete = NULL((void*)0);
9522 cur = root;
9523 while (cur != NULL((void*)0)) {
9524 if (delete != NULL((void*)0)) {
9525 xmlUnlinkNode(delete);
9526 xmlFreeNode(delete);
9527 delete = NULL((void*)0);
9528 }
9529 if (cur->type == XML_TEXT_NODE) {
9530 if (IS_BLANK_NODE(cur)(((cur)->type == XML_TEXT_NODE) && (xmlSchemaIsBlank
((cur)->content, -1)))
) {
9531 if (xmlNodeGetSpacePreserve(cur) != 1) {
9532 delete = cur;
9533 }
9534 }
9535 } else if ((cur->type != XML_ELEMENT_NODE) &&
9536 (cur->type != XML_CDATA_SECTION_NODE)) {
9537 delete = cur;
9538 goto skip_children;
9539 }
9540
9541 /*
9542 * Skip to next node
9543 */
9544 if (cur->children != NULL((void*)0)) {
9545 if ((cur->children->type != XML_ENTITY_DECL) &&
9546 (cur->children->type != XML_ENTITY_REF_NODE) &&
9547 (cur->children->type != XML_ENTITY_NODE)) {
9548 cur = cur->children;
9549 continue;
9550 }
9551 }
9552 skip_children:
9553 if (cur->next != NULL((void*)0)) {
9554 cur = cur->next;
9555 continue;
9556 }
9557
9558 do {
9559 cur = cur->parent;
9560 if (cur == NULL((void*)0))
9561 break;
9562 if (cur == root) {
9563 cur = NULL((void*)0);
9564 break;
9565 }
9566 if (cur->next != NULL((void*)0)) {
9567 cur = cur->next;
9568 break;
9569 }
9570 } while (cur != NULL((void*)0));
9571 }
9572 if (delete != NULL((void*)0)) {
9573 xmlUnlinkNode(delete);
9574 xmlFreeNode(delete);
9575 delete = NULL((void*)0);
9576 }
9577}
9578
9579
9580static void
9581xmlSchemaClearSchemaDefaults(xmlSchemaPtr schema)
9582{
9583 if (schema->flags & XML_SCHEMAS_QUALIF_ELEM1 << 0)
9584 schema->flags ^= XML_SCHEMAS_QUALIF_ELEM1 << 0;
9585
9586 if (schema->flags & XML_SCHEMAS_QUALIF_ATTR1 << 1)
9587 schema->flags ^= XML_SCHEMAS_QUALIF_ATTR1 << 1;
9588
9589 if (schema->flags & XML_SCHEMAS_FINAL_DEFAULT_EXTENSION1 << 2)
9590 schema->flags ^= XML_SCHEMAS_FINAL_DEFAULT_EXTENSION1 << 2;
9591 if (schema->flags & XML_SCHEMAS_FINAL_DEFAULT_RESTRICTION1 << 3)
9592 schema->flags ^= XML_SCHEMAS_FINAL_DEFAULT_RESTRICTION1 << 3;
9593 if (schema->flags & XML_SCHEMAS_FINAL_DEFAULT_LIST1 << 4)
9594 schema->flags ^= XML_SCHEMAS_FINAL_DEFAULT_LIST1 << 4;
9595 if (schema->flags & XML_SCHEMAS_FINAL_DEFAULT_UNION1 << 5)
9596 schema->flags ^= XML_SCHEMAS_FINAL_DEFAULT_UNION1 << 5;
9597
9598 if (schema->flags & XML_SCHEMAS_BLOCK_DEFAULT_EXTENSION1 << 6)
9599 schema->flags ^= XML_SCHEMAS_BLOCK_DEFAULT_EXTENSION1 << 6;
9600 if (schema->flags & XML_SCHEMAS_BLOCK_DEFAULT_RESTRICTION1 << 7)
9601 schema->flags ^= XML_SCHEMAS_BLOCK_DEFAULT_RESTRICTION1 << 7;
9602 if (schema->flags & XML_SCHEMAS_BLOCK_DEFAULT_SUBSTITUTION1 << 8)
9603 schema->flags ^= XML_SCHEMAS_BLOCK_DEFAULT_SUBSTITUTION1 << 8;
9604}
9605
9606static int
9607xmlSchemaParseSchemaElement(xmlSchemaParserCtxtPtr ctxt,
9608 xmlSchemaPtr schema,
9609 xmlNodePtr node)
9610{
9611 xmlAttrPtr attr;
9612 const xmlChar *val;
9613 int res = 0, oldErrs = ctxt->nberrors;
9614
9615 /*
9616 * Those flags should be moved to the parser context flags,
9617 * since they are not visible at the component level. I.e.
9618 * they are used if processing schema *documents* only.
9619 */
9620 res = xmlSchemaPValAttrID(ctxt, node, BAD_CAST(xmlChar *) "id");
9621 HFAILUREif (res == -1) goto exit_failure;;
9622
9623 /*
9624 * Since the version is of type xs:token, we won't bother to
9625 * check it.
9626 */
9627 /* REMOVED:
9628 attr = xmlSchemaGetPropNode(node, "version");
9629 if (attr != NULL) {
9630 res = xmlSchemaPValAttrNode(ctxt, NULL, NULL, attr,
9631 xmlSchemaGetBuiltInType(XML_SCHEMAS_TOKEN), &val);
9632 HFAILURE;
9633 }
9634 */
9635 attr = xmlSchemaGetPropNode(node, "targetNamespace");
9636 if (attr != NULL((void*)0)) {
9637 res = xmlSchemaPValAttrNode(ctxt, NULL((void*)0), attr,
9638 xmlSchemaGetBuiltInType(XML_SCHEMAS_ANYURI), NULL((void*)0));
9639 HFAILUREif (res == -1) goto exit_failure;;
9640 if (res != 0) {
9641 ctxt->stop = XML_SCHEMAP_S4S_ATTR_INVALID_VALUE;
9642 goto exit;
9643 }
9644 }
9645 attr = xmlSchemaGetPropNode(node, "elementFormDefault");
9646 if (attr != NULL((void*)0)) {
9647 val = xmlSchemaGetNodeContent(ctxt, (xmlNodePtr) attr);
9648 res = xmlSchemaPValAttrFormDefault(val, &schema->flags,
9649 XML_SCHEMAS_QUALIF_ELEM1 << 0);
9650 HFAILUREif (res == -1) goto exit_failure;;
9651 if (res != 0) {
9652 xmlSchemaPSimpleTypeErr(ctxt,
9653 XML_SCHEMAP_ELEMFORMDEFAULT_VALUE,
9654 NULL((void*)0), (xmlNodePtr) attr, NULL((void*)0),
9655 "(qualified | unqualified)", val, NULL((void*)0), NULL((void*)0), NULL((void*)0));
9656 }
9657 }
9658 attr = xmlSchemaGetPropNode(node, "attributeFormDefault");
9659 if (attr != NULL((void*)0)) {
9660 val = xmlSchemaGetNodeContent(ctxt, (xmlNodePtr) attr);
9661 res = xmlSchemaPValAttrFormDefault(val, &schema->flags,
9662 XML_SCHEMAS_QUALIF_ATTR1 << 1);
9663 HFAILUREif (res == -1) goto exit_failure;;
9664 if (res != 0) {
9665 xmlSchemaPSimpleTypeErr(ctxt,
9666 XML_SCHEMAP_ATTRFORMDEFAULT_VALUE,
9667 NULL((void*)0), (xmlNodePtr) attr, NULL((void*)0),
9668 "(qualified | unqualified)", val, NULL((void*)0), NULL((void*)0), NULL((void*)0));
9669 }
9670 }
9671 attr = xmlSchemaGetPropNode(node, "finalDefault");
9672 if (attr != NULL((void*)0)) {
9673 val = xmlSchemaGetNodeContent(ctxt, (xmlNodePtr) attr);
9674 res = xmlSchemaPValAttrBlockFinal(val, &(schema->flags), -1,
9675 XML_SCHEMAS_FINAL_DEFAULT_EXTENSION1 << 2,
9676 XML_SCHEMAS_FINAL_DEFAULT_RESTRICTION1 << 3,
9677 -1,
9678 XML_SCHEMAS_FINAL_DEFAULT_LIST1 << 4,
9679 XML_SCHEMAS_FINAL_DEFAULT_UNION1 << 5);
9680 HFAILUREif (res == -1) goto exit_failure;;
9681 if (res != 0) {
9682 xmlSchemaPSimpleTypeErr(ctxt,
9683 XML_SCHEMAP_S4S_ATTR_INVALID_VALUE,
9684 NULL((void*)0), (xmlNodePtr) attr, NULL((void*)0),
9685 "(#all | List of (extension | restriction | list | union))",
9686 val, NULL((void*)0), NULL((void*)0), NULL((void*)0));
9687 }
9688 }
9689 attr = xmlSchemaGetPropNode(node, "blockDefault");
9690 if (attr != NULL((void*)0)) {
9691 val = xmlSchemaGetNodeContent(ctxt, (xmlNodePtr) attr);
9692 res = xmlSchemaPValAttrBlockFinal(val, &(schema->flags), -1,
9693 XML_SCHEMAS_BLOCK_DEFAULT_EXTENSION1 << 6,
9694 XML_SCHEMAS_BLOCK_DEFAULT_RESTRICTION1 << 7,
9695 XML_SCHEMAS_BLOCK_DEFAULT_SUBSTITUTION1 << 8, -1, -1);
9696 HFAILUREif (res == -1) goto exit_failure;;
9697 if (res != 0) {
9698 xmlSchemaPSimpleTypeErr(ctxt,
9699 XML_SCHEMAP_S4S_ATTR_INVALID_VALUE,
9700 NULL((void*)0), (xmlNodePtr) attr, NULL((void*)0),
9701 "(#all | List of (extension | restriction | substitution))",
9702 val, NULL((void*)0), NULL((void*)0), NULL((void*)0));
9703 }
9704 }
9705
9706exit:
9707 if (oldErrs != ctxt->nberrors)
9708 res = ctxt->err;
9709 return(res);
9710exit_failure:
9711 return(-1);
9712}
9713
9714/**
9715 * xmlSchemaParseSchemaTopLevel:
9716 * @ctxt: a schema validation context
9717 * @schema: the schemas
9718 * @nodes: the list of top level nodes
9719 *
9720 * Returns the internal XML Schema structure built from the resource or
9721 * NULL in case of error
9722 */
9723static int
9724xmlSchemaParseSchemaTopLevel(xmlSchemaParserCtxtPtr ctxt,
9725 xmlSchemaPtr schema, xmlNodePtr nodes)
9726{
9727 xmlNodePtr child;
9728 xmlSchemaAnnotPtr annot;
9729 int res = 0, oldErrs, tmpOldErrs;
9730
9731 if ((ctxt == NULL((void*)0)) || (schema == NULL((void*)0)) || (nodes == NULL((void*)0)))
9732 return(-1);
9733
9734 oldErrs = ctxt->nberrors;
9735 child = nodes;
9736 while ((IS_SCHEMA(child, "include")((child != ((void*)0)) && (child->ns != ((void*)0)
) && (xmlStrEqual(child->name, (const xmlChar *) "include"
)) && (xmlStrEqual(child->ns->href, xmlSchemaNs
)))
) ||
9737 (IS_SCHEMA(child, "import")((child != ((void*)0)) && (child->ns != ((void*)0)
) && (xmlStrEqual(child->name, (const xmlChar *) "import"
)) && (xmlStrEqual(child->ns->href, xmlSchemaNs
)))
) ||
9738 (IS_SCHEMA(child, "redefine")((child != ((void*)0)) && (child->ns != ((void*)0)
) && (xmlStrEqual(child->name, (const xmlChar *) "redefine"
)) && (xmlStrEqual(child->ns->href, xmlSchemaNs
)))
) ||
9739 (IS_SCHEMA(child, "annotation")((child != ((void*)0)) && (child->ns != ((void*)0)
) && (xmlStrEqual(child->name, (const xmlChar *) "annotation"
)) && (xmlStrEqual(child->ns->href, xmlSchemaNs
)))
)) {
9740 if (IS_SCHEMA(child, "annotation")((child != ((void*)0)) && (child->ns != ((void*)0)
) && (xmlStrEqual(child->name, (const xmlChar *) "annotation"
)) && (xmlStrEqual(child->ns->href, xmlSchemaNs
)))
) {
9741 annot = xmlSchemaParseAnnotation(ctxt, child, 1);
9742 if (schema->annot == NULL((void*)0))
9743 schema->annot = annot;
9744 else
9745 xmlSchemaFreeAnnot(annot);
9746 } else if (IS_SCHEMA(child, "import")((child != ((void*)0)) && (child->ns != ((void*)0)
) && (xmlStrEqual(child->name, (const xmlChar *) "import"
)) && (xmlStrEqual(child->ns->href, xmlSchemaNs
)))
) {
9747 tmpOldErrs = ctxt->nberrors;
9748 res = xmlSchemaParseImport(ctxt, schema, child);
9749 HFAILUREif (res == -1) goto exit_failure;;
9750 HSTOP(ctxt)if ((ctxt)->stop) goto exit;;
9751 if (tmpOldErrs != ctxt->nberrors)
9752 goto exit;
9753 } else if (IS_SCHEMA(child, "include")((child != ((void*)0)) && (child->ns != ((void*)0)
) && (xmlStrEqual(child->name, (const xmlChar *) "include"
)) && (xmlStrEqual(child->ns->href, xmlSchemaNs
)))
) {
9754 tmpOldErrs = ctxt->nberrors;
9755 res = xmlSchemaParseInclude(ctxt, schema, child);
9756 HFAILUREif (res == -1) goto exit_failure;;
9757 HSTOP(ctxt)if ((ctxt)->stop) goto exit;;
9758 if (tmpOldErrs != ctxt->nberrors)
9759 goto exit;
9760 } else if (IS_SCHEMA(child, "redefine")((child != ((void*)0)) && (child->ns != ((void*)0)
) && (xmlStrEqual(child->name, (const xmlChar *) "redefine"
)) && (xmlStrEqual(child->ns->href, xmlSchemaNs
)))
) {
9761 tmpOldErrs = ctxt->nberrors;
9762 res = xmlSchemaParseRedefine(ctxt, schema, child);
9763 HFAILUREif (res == -1) goto exit_failure;;
9764 HSTOP(ctxt)if ((ctxt)->stop) goto exit;;
9765 if (tmpOldErrs != ctxt->nberrors)
9766 goto exit;
9767 }
9768 child = child->next;
9769 }
9770 /*
9771 * URGENT TODO: Change the functions to return int results.
9772 * We need especially to catch internal errors.
9773 */
9774 while (child != NULL((void*)0)) {
9775 if (IS_SCHEMA(child, "complexType")((child != ((void*)0)) && (child->ns != ((void*)0)
) && (xmlStrEqual(child->name, (const xmlChar *) "complexType"
)) && (xmlStrEqual(child->ns->href, xmlSchemaNs
)))
) {
9776 xmlSchemaParseComplexType(ctxt, schema, child, 1);
9777 child = child->next;
9778 } else if (IS_SCHEMA(child, "simpleType")((child != ((void*)0)) && (child->ns != ((void*)0)
) && (xmlStrEqual(child->name, (const xmlChar *) "simpleType"
)) && (xmlStrEqual(child->ns->href, xmlSchemaNs
)))
) {
9779 xmlSchemaParseSimpleType(ctxt, schema, child, 1);
9780 child = child->next;
9781 } else if (IS_SCHEMA(child, "element")((child != ((void*)0)) && (child->ns != ((void*)0)
) && (xmlStrEqual(child->name, (const xmlChar *) "element"
)) && (xmlStrEqual(child->ns->href, xmlSchemaNs
)))
) {
9782 xmlSchemaParseElement(ctxt, schema, child, NULL((void*)0), 1);
9783 child = child->next;
9784 } else if (IS_SCHEMA(child, "attribute")((child != ((void*)0)) && (child->ns != ((void*)0)
) && (xmlStrEqual(child->name, (const xmlChar *) "attribute"
)) && (xmlStrEqual(child->ns->href, xmlSchemaNs
)))
) {
9785 xmlSchemaParseGlobalAttribute(ctxt, schema, child);
9786 child = child->next;
9787 } else if (IS_SCHEMA(child, "attributeGroup")((child != ((void*)0)) && (child->ns != ((void*)0)
) && (xmlStrEqual(child->name, (const xmlChar *) "attributeGroup"
)) && (xmlStrEqual(child->ns->href, xmlSchemaNs
)))
) {
9788 xmlSchemaParseAttributeGroupDefinition(ctxt, schema, child);
9789 child = child->next;
9790 } else if (IS_SCHEMA(child, "group")((child != ((void*)0)) && (child->ns != ((void*)0)
) && (xmlStrEqual(child->name, (const xmlChar *) "group"
)) && (xmlStrEqual(child->ns->href, xmlSchemaNs
)))
) {
9791 xmlSchemaParseModelGroupDefinition(ctxt, schema, child);
9792 child = child->next;
9793 } else if (IS_SCHEMA(child, "notation")((child != ((void*)0)) && (child->ns != ((void*)0)
) && (xmlStrEqual(child->name, (const xmlChar *) "notation"
)) && (xmlStrEqual(child->ns->href, xmlSchemaNs
)))
) {
9794 xmlSchemaParseNotation(ctxt, schema, child);
9795 child = child->next;
9796 } else {
9797 xmlSchemaPContentErr(ctxt,
9798 XML_SCHEMAP_S4S_ELEM_NOT_ALLOWED,
9799 NULL((void*)0), child->parent, child,
9800 NULL((void*)0), "((include | import | redefine | annotation)*, "
9801 "(((simpleType | complexType | group | attributeGroup) "
9802 "| element | attribute | notation), annotation*)*)");
9803 child = child->next;
9804 }
9805 while (IS_SCHEMA(child, "annotation")((child != ((void*)0)) && (child->ns != ((void*)0)
) && (xmlStrEqual(child->name, (const xmlChar *) "annotation"
)) && (xmlStrEqual(child->ns->href, xmlSchemaNs
)))
) {
9806 /*
9807 * TODO: We should add all annotations.
9808 */
9809 annot = xmlSchemaParseAnnotation(ctxt, child, 1);
9810 if (schema->annot == NULL((void*)0))
9811 schema->annot = annot;
9812 else
9813 xmlSchemaFreeAnnot(annot);
9814 child = child->next;
9815 }
9816 }
9817exit:
9818 ctxt->ctxtType = NULL((void*)0);
9819 if (oldErrs != ctxt->nberrors)
9820 res = ctxt->err;
9821 return(res);
9822exit_failure:
9823 return(-1);
9824}
9825
9826static xmlSchemaSchemaRelationPtr
9827xmlSchemaSchemaRelationCreate(void)
9828{
9829 xmlSchemaSchemaRelationPtr ret;
9830
9831 ret = (xmlSchemaSchemaRelationPtr)
9832 xmlMalloc(sizeof(xmlSchemaSchemaRelation));
9833 if (ret == NULL((void*)0)) {
9834 xmlSchemaPErrMemory(NULL((void*)0), "allocating schema relation", NULL((void*)0));
9835 return(NULL((void*)0));
9836 }
9837 memset(ret, 0, sizeof(xmlSchemaSchemaRelation));
9838 return(ret);
9839}
9840
9841#if 0
9842static void
9843xmlSchemaSchemaRelationFree(xmlSchemaSchemaRelationPtr rel)
9844{
9845 xmlFree(rel);
9846}
9847#endif
9848
9849static void
9850xmlSchemaRedefListFree(xmlSchemaRedefPtr redef)
9851{
9852 xmlSchemaRedefPtr prev;
9853
9854 while (redef != NULL((void*)0)) {
9855 prev = redef;
9856 redef = redef->next;
9857 xmlFree(prev);
9858 }
9859}
9860
9861static void
9862xmlSchemaConstructionCtxtFree(xmlSchemaConstructionCtxtPtr con)
9863{
9864 /*
9865 * After the construction context has been freed, there will be
9866 * no schema graph available any more. Only the schema buckets
9867 * will stay alive, which are put into the "schemasImports" and
9868 * "includes" slots of the xmlSchema.
9869 */
9870 if (con->buckets != NULL((void*)0))
9871 xmlSchemaItemListFree(con->buckets);
9872 if (con->pending != NULL((void*)0))
9873 xmlSchemaItemListFree(con->pending);
9874 if (con->substGroups != NULL((void*)0))
9875 xmlHashFree(con->substGroups, xmlSchemaSubstGroupFreeEntry);
9876 if (con->redefs != NULL((void*)0))
9877 xmlSchemaRedefListFree(con->redefs);
9878 if (con->dict != NULL((void*)0))
9879 xmlDictFree(con->dict);
9880 xmlFree(con);
9881}
9882
9883static xmlSchemaConstructionCtxtPtr
9884xmlSchemaConstructionCtxtCreate(xmlDictPtr dict)
9885{
9886 xmlSchemaConstructionCtxtPtr ret;
9887
9888 ret = (xmlSchemaConstructionCtxtPtr)
9889 xmlMalloc(sizeof(xmlSchemaConstructionCtxt));
9890 if (ret == NULL((void*)0)) {
9891 xmlSchemaPErrMemory(NULL((void*)0),
9892 "allocating schema construction context", NULL((void*)0));
9893 return (NULL((void*)0));
9894 }
9895 memset(ret, 0, sizeof(xmlSchemaConstructionCtxt));
9896
9897 ret->buckets = xmlSchemaItemListCreate();
9898 if (ret->buckets == NULL((void*)0)) {
9899 xmlSchemaPErrMemory(NULL((void*)0),
9900 "allocating list of schema buckets", NULL((void*)0));
9901 xmlFree(ret);
9902 return (NULL((void*)0));
9903 }
9904 ret->pending = xmlSchemaItemListCreate();
9905 if (ret->pending == NULL((void*)0)) {
9906 xmlSchemaPErrMemory(NULL((void*)0),
9907 "allocating list of pending global components", NULL((void*)0));
9908 xmlSchemaConstructionCtxtFree(ret);
9909 return (NULL((void*)0));
9910 }
9911 ret->dict = dict;
9912 xmlDictReference(dict);
9913 return(ret);
9914}
9915
9916static xmlSchemaParserCtxtPtr
9917xmlSchemaParserCtxtCreate(void)
9918{
9919 xmlSchemaParserCtxtPtr ret;
9920
9921 ret = (xmlSchemaParserCtxtPtr) xmlMalloc(sizeof(xmlSchemaParserCtxt));
9922 if (ret == NULL((void*)0)) {
9923 xmlSchemaPErrMemory(NULL((void*)0), "allocating schema parser context",
9924 NULL((void*)0));
9925 return (NULL((void*)0));
9926 }
9927 memset(ret, 0, sizeof(xmlSchemaParserCtxt));
9928 ret->type = XML_SCHEMA_CTXT_PARSER1;
9929 ret->attrProhibs = xmlSchemaItemListCreate();
9930 if (ret->attrProhibs == NULL((void*)0)) {
9931 xmlFree(ret);
9932 return(NULL((void*)0));
9933 }
9934 return(ret);
9935}
9936
9937/**
9938 * xmlSchemaNewParserCtxtUseDict:
9939 * @URL: the location of the schema
9940 * @dict: the dictionary to be used
9941 *
9942 * Create an XML Schemas parse context for that file/resource expected
9943 * to contain an XML Schemas file.
9944 *
9945 * Returns the parser context or NULL in case of error
9946 */
9947static xmlSchemaParserCtxtPtr
9948xmlSchemaNewParserCtxtUseDict(const char *URL, xmlDictPtr dict)
9949{
9950 xmlSchemaParserCtxtPtr ret;
9951
9952 ret = xmlSchemaParserCtxtCreate();
9953 if (ret == NULL((void*)0))
9954 return (NULL((void*)0));
9955 ret->dict = dict;
9956 xmlDictReference(dict);
9957 if (URL != NULL((void*)0))
9958 ret->URL = xmlDictLookup(dict, (const xmlChar *) URL, -1);
9959 return (ret);
9960}
9961
9962static int
9963xmlSchemaCreatePCtxtOnVCtxt(xmlSchemaValidCtxtPtr vctxt)
9964{
9965 if (vctxt->pctxt == NULL((void*)0)) {
9966 if (vctxt->schema != NULL((void*)0))
9967 vctxt->pctxt =
9968 xmlSchemaNewParserCtxtUseDict("*", vctxt->schema->dict);
9969 else
9970 vctxt->pctxt = xmlSchemaNewParserCtxt("*");
9971 if (vctxt->pctxt == NULL((void*)0)) {
9972 VERROR_INT("xmlSchemaCreatePCtxtOnVCtxt",xmlSchemaInternalErr((xmlSchemaAbstractCtxtPtr) vctxt, "xmlSchemaCreatePCtxtOnVCtxt"
, "failed to create a temp. parser context");
9973 "failed to create a temp. parser context")xmlSchemaInternalErr((xmlSchemaAbstractCtxtPtr) vctxt, "xmlSchemaCreatePCtxtOnVCtxt"
, "failed to create a temp. parser context");
;
9974 return (-1);
9975 }
9976 /* TODO: Pass user data. */
9977 xmlSchemaSetParserErrors(vctxt->pctxt, vctxt->error,
9978 vctxt->warning, vctxt->errCtxt);
9979 xmlSchemaSetParserStructuredErrors(vctxt->pctxt, vctxt->serror,
9980 vctxt->errCtxt);
9981 }
9982 return (0);
9983}
9984
9985/**
9986 * xmlSchemaGetSchemaBucket:
9987 * @pctxt: the schema parser context
9988 * @schemaLocation: the URI of the schema document
9989 *
9990 * Returns a schema bucket if it was already parsed.
9991 *
9992 * Returns a schema bucket if it was already parsed from
9993 * @schemaLocation, NULL otherwise.
9994 */
9995static xmlSchemaBucketPtr
9996xmlSchemaGetSchemaBucket(xmlSchemaParserCtxtPtr pctxt,
9997 const xmlChar *schemaLocation)
9998{
9999 xmlSchemaBucketPtr cur;
10000 xmlSchemaItemListPtr list;
10001
10002 list = pctxt->constructor->buckets;
10003 if (list->nbItems == 0)
10004 return(NULL((void*)0));
10005 else {
10006 int i;
10007 for (i = 0; i < list->nbItems; i++) {
10008 cur = (xmlSchemaBucketPtr) list->items[i];
10009 /* Pointer comparison! */
10010 if (cur->schemaLocation == schemaLocation)
10011 return(cur);
10012 }
10013 }
10014 return(NULL((void*)0));
10015}
10016
10017static xmlSchemaBucketPtr
10018xmlSchemaGetChameleonSchemaBucket(xmlSchemaParserCtxtPtr pctxt,
10019 const xmlChar *schemaLocation,
10020 const xmlChar *targetNamespace)
10021{
10022 xmlSchemaBucketPtr cur;
10023 xmlSchemaItemListPtr list;
10024
10025 list = pctxt->constructor->buckets;
10026 if (list->nbItems == 0)
10027 return(NULL((void*)0));
10028 else {
10029 int i;
10030 for (i = 0; i < list->nbItems; i++) {
10031 cur = (xmlSchemaBucketPtr) list->items[i];
10032 /* Pointer comparison! */
10033 if ((cur->origTargetNamespace == NULL((void*)0)) &&
10034 (cur->schemaLocation == schemaLocation) &&
10035 (cur->targetNamespace == targetNamespace))
10036 return(cur);
10037 }
10038 }
10039 return(NULL((void*)0));
10040}
10041
10042
10043#define IS_BAD_SCHEMA_DOC(b)(((b)->doc == ((void*)0)) && ((b)->schemaLocation
!= ((void*)0)))
\
10044 (((b)->doc == NULL((void*)0)) && ((b)->schemaLocation != NULL((void*)0)))
10045
10046static xmlSchemaBucketPtr
10047xmlSchemaGetSchemaBucketByTNS(xmlSchemaParserCtxtPtr pctxt,
10048 const xmlChar *targetNamespace,
10049 int imported)
10050{
10051 xmlSchemaBucketPtr cur;
10052 xmlSchemaItemListPtr list;
10053
10054 list = pctxt->constructor->buckets;
10055 if (list->nbItems == 0)
10056 return(NULL((void*)0));
10057 else {
10058 int i;
10059 for (i = 0; i < list->nbItems; i++) {
10060 cur = (xmlSchemaBucketPtr) list->items[i];
10061 if ((! IS_BAD_SCHEMA_DOC(cur)(((cur)->doc == ((void*)0)) && ((cur)->schemaLocation
!= ((void*)0)))
) &&
10062 (cur->origTargetNamespace == targetNamespace) &&
10063 ((imported && cur->imported) ||
10064 ((!imported) && (!cur->imported))))
10065 return(cur);
10066 }
10067 }
10068 return(NULL((void*)0));
10069}
10070
10071static int
10072xmlSchemaParseNewDocWithContext(xmlSchemaParserCtxtPtr pctxt,
10073 xmlSchemaPtr schema,
10074 xmlSchemaBucketPtr bucket)
10075{
10076 int oldFlags;
10077 xmlDocPtr oldDoc;
10078 xmlNodePtr node;
10079 int ret, oldErrs;
10080 xmlSchemaBucketPtr oldbucket = pctxt->constructor->bucket;
10081
10082 /*
10083 * Save old values; reset the *main* schema.
10084 * URGENT TODO: This is not good; move the per-document information
10085 * to the parser. Get rid of passing the main schema to the
10086 * parsing functions.
10087 */
10088 oldFlags = schema->flags;
10089 oldDoc = schema->doc;
10090 if (schema->flags != 0)
10091 xmlSchemaClearSchemaDefaults(schema);
10092 schema->doc = bucket->doc;
10093 pctxt->schema = schema;
10094 /*
10095 * Keep the current target namespace on the parser *not* on the
10096 * main schema.
10097 */
10098 pctxt->targetNamespace = bucket->targetNamespace;
10099 WXS_CONSTRUCTOR(pctxt)(pctxt)->constructor->bucket = bucket;
10100
10101 if ((bucket->targetNamespace != NULL((void*)0)) &&
10102 xmlStrEqual(bucket->targetNamespace, xmlSchemaNs)) {
10103 /*
10104 * We are parsing the schema for schemas!
10105 */
10106 pctxt->isS4S = 1;
10107 }
10108 /* Mark it as parsed, even if parsing fails. */
10109 bucket->parsed++;
10110 /* Compile the schema doc. */
10111 node = xmlDocGetRootElement(bucket->doc);
10112 ret = xmlSchemaParseSchemaElement(pctxt, schema, node);
10113 if (ret != 0)
10114 goto exit;
10115 /* An empty schema; just get out. */
10116 if (node->children == NULL((void*)0))
10117 goto exit;
10118 oldErrs = pctxt->nberrors;
10119 ret = xmlSchemaParseSchemaTopLevel(pctxt, schema, node->children);
10120 if (ret != 0)
10121 goto exit;
10122 /*
10123 * TODO: Not nice, but I'm not 100% sure we will get always an error
10124 * as a result of the above functions; so better rely on pctxt->err
10125 * as well.
10126 */
10127 if ((ret == 0) && (oldErrs != pctxt->nberrors)) {
10128 ret = pctxt->err;
10129 goto exit;
10130 }
10131
10132exit:
10133 WXS_CONSTRUCTOR(pctxt)(pctxt)->constructor->bucket = oldbucket;
10134 /* Restore schema values. */
10135 schema->doc = oldDoc;
10136 schema->flags = oldFlags;
10137 return(ret);
10138}
10139
10140static int
10141xmlSchemaParseNewDoc(xmlSchemaParserCtxtPtr pctxt,
10142 xmlSchemaPtr schema,
10143 xmlSchemaBucketPtr bucket)
10144{
10145 xmlSchemaParserCtxtPtr newpctxt;
10146 int res = 0;
10147
10148 if (bucket == NULL((void*)0))
10149 return(0);
10150 if (bucket->parsed) {
10151 PERROR_INT("xmlSchemaParseNewDoc",xmlSchemaInternalErr((xmlSchemaAbstractCtxtPtr) pctxt, "xmlSchemaParseNewDoc"
, "reparsing a schema doc");
10152 "reparsing a schema doc")xmlSchemaInternalErr((xmlSchemaAbstractCtxtPtr) pctxt, "xmlSchemaParseNewDoc"
, "reparsing a schema doc");
;
10153 return(-1);
10154 }
10155 if (bucket->doc == NULL((void*)0)) {
10156 PERROR_INT("xmlSchemaParseNewDoc",xmlSchemaInternalErr((xmlSchemaAbstractCtxtPtr) pctxt, "xmlSchemaParseNewDoc"
, "parsing a schema doc, but there's no doc");
10157 "parsing a schema doc, but there's no doc")xmlSchemaInternalErr((xmlSchemaAbstractCtxtPtr) pctxt, "xmlSchemaParseNewDoc"
, "parsing a schema doc, but there's no doc");
;
10158 return(-1);
10159 }
10160 if (pctxt->constructor == NULL((void*)0)) {
10161 PERROR_INT("xmlSchemaParseNewDoc",xmlSchemaInternalErr((xmlSchemaAbstractCtxtPtr) pctxt, "xmlSchemaParseNewDoc"
, "no constructor");
10162 "no constructor")xmlSchemaInternalErr((xmlSchemaAbstractCtxtPtr) pctxt, "xmlSchemaParseNewDoc"
, "no constructor");
;
10163 return(-1);
10164 }
10165 /* Create and init the temporary parser context. */
10166 newpctxt = xmlSchemaNewParserCtxtUseDict(
10167 (const char *) bucket->schemaLocation, pctxt->dict);
10168 if (newpctxt == NULL((void*)0))
10169 return(-1);
10170 newpctxt->constructor = pctxt->constructor;
10171 /*
10172 * TODO: Can we avoid that the parser knows about the main schema?
10173 * It would be better if he knows about the current schema bucket
10174 * only.
10175 */
10176 newpctxt->schema = schema;
10177 xmlSchemaSetParserErrors(newpctxt, pctxt->error, pctxt->warning,
10178 pctxt->errCtxt);
10179 xmlSchemaSetParserStructuredErrors(newpctxt, pctxt->serror,
10180 pctxt->errCtxt);
10181 newpctxt->counter = pctxt->counter;
10182
10183
10184 res = xmlSchemaParseNewDocWithContext(newpctxt, schema, bucket);
10185
10186 /* Channel back errors and cleanup the temporary parser context. */
10187 if (res != 0)
10188 pctxt->err = res;
10189 pctxt->nberrors += newpctxt->nberrors;
10190 pctxt->counter = newpctxt->counter;
10191 newpctxt->constructor = NULL((void*)0);
10192 /* Free the parser context. */
10193 xmlSchemaFreeParserCtxt(newpctxt);
10194 return(res);
10195}
10196
10197static void
10198xmlSchemaSchemaRelationAddChild(xmlSchemaBucketPtr bucket,
10199 xmlSchemaSchemaRelationPtr rel)
10200{
10201 xmlSchemaSchemaRelationPtr cur = bucket->relations;
10202
10203 if (cur == NULL((void*)0)) {
10204 bucket->relations = rel;
10205 return;
10206 }
10207 while (cur->next != NULL((void*)0))
10208 cur = cur->next;
10209 cur->next = rel;
10210}
10211
10212
10213static const xmlChar *
10214xmlSchemaBuildAbsoluteURI(xmlDictPtr dict, const xmlChar* location,
10215 xmlNodePtr ctxtNode)
10216{
10217 /*
10218 * Build an absolute location URI.
10219 */
10220 if (location != NULL((void*)0)) {
10221 if (ctxtNode == NULL((void*)0))
10222 return(location);
10223 else {
10224 xmlChar *base, *URI;
10225 const xmlChar *ret = NULL((void*)0);
10226
10227 base = xmlNodeGetBase(ctxtNode->doc, ctxtNode);
10228 if (base == NULL((void*)0)) {
10229 URI = xmlBuildURI(location, ctxtNode->doc->URL);
10230 } else {
10231 URI = xmlBuildURI(location, base);
10232 xmlFree(base);
10233 }
10234 if (URI != NULL((void*)0)) {
10235 ret = xmlDictLookup(dict, URI, -1);
10236 xmlFree(URI);
10237 return(ret);
10238 }
10239 }
10240 }
10241 return(NULL((void*)0));
10242}
10243
10244
10245
10246/**
10247 * xmlSchemaAddSchemaDoc:
10248 * @pctxt: a schema validation context
10249 * @schema: the schema being built
10250 * @node: a subtree containing XML Schema information
10251 *
10252 * Parse an included (and to-be-redefined) XML schema document.
10253 *
10254 * Returns 0 on success, a positive error code on errors and
10255 * -1 in case of an internal or API error.
10256 */
10257
10258static int
10259xmlSchemaAddSchemaDoc(xmlSchemaParserCtxtPtr pctxt,
10260 int type, /* import or include or redefine */
10261 const xmlChar *schemaLocation,
10262 xmlDocPtr schemaDoc,
10263 const char *schemaBuffer,
10264 int schemaBufferLen,
10265 xmlNodePtr invokingNode,
10266 const xmlChar *sourceTargetNamespace,
10267 const xmlChar *importNamespace,
10268 xmlSchemaBucketPtr *bucket)
10269{
10270 const xmlChar *targetNamespace = NULL((void*)0);
10271 xmlSchemaSchemaRelationPtr relation = NULL((void*)0);
10272 xmlDocPtr doc = NULL((void*)0);
10273 int res = 0, err = 0, located = 0, preserveDoc = 0;
10274 xmlSchemaBucketPtr bkt = NULL((void*)0);
10275
10276 if (bucket != NULL((void*)0))
10277 *bucket = NULL((void*)0);
10278
10279 switch (type) {
10280 case XML_SCHEMA_SCHEMA_IMPORT1:
10281 case XML_SCHEMA_SCHEMA_MAIN0:
10282 err = XML_SCHEMAP_SRC_IMPORT;
10283 break;
10284 case XML_SCHEMA_SCHEMA_INCLUDE2:
10285 err = XML_SCHEMAP_SRC_INCLUDE;
10286 break;
10287 case XML_SCHEMA_SCHEMA_REDEFINE3:
10288 err = XML_SCHEMAP_SRC_REDEFINE;
10289 break;
10290 }
10291
10292
10293 /* Special handling for the main schema:
10294 * skip the location and relation logic and just parse the doc.
10295 * We need just a bucket to be returned in this case.
10296 */
10297 if ((type == XML_SCHEMA_SCHEMA_MAIN0) || (! WXS_HAS_BUCKETS(pctxt)( (((pctxt))->constructor->buckets != ((void*)0)) &&
(((pctxt))->constructor->buckets->nbItems > 0) )
))
10298 goto doc_load;
10299
10300 /* Note that we expect the location to be an absolute URI. */
10301 if (schemaLocation != NULL((void*)0)) {
10302 bkt = xmlSchemaGetSchemaBucket(pctxt, schemaLocation);
10303 if ((bkt != NULL((void*)0)) &&
10304 (pctxt->constructor->bucket == bkt)) {
10305 /* Report self-imports/inclusions/redefinitions. */
10306
10307 xmlSchemaCustomErr(ACTXT_CAST(xmlSchemaAbstractCtxtPtr) pctxt, err,
10308 invokingNode, NULL((void*)0),
10309 "The schema must not import/include/redefine itself",
10310 NULL((void*)0), NULL((void*)0));
10311 goto exit;
10312 }
10313 }
10314 /*
10315 * Create a relation for the graph of schemas.
10316 */
10317 relation = xmlSchemaSchemaRelationCreate();
10318 if (relation == NULL((void*)0))
10319 return(-1);
10320 xmlSchemaSchemaRelationAddChild(pctxt->constructor->bucket,
10321 relation);
10322 relation->type = type;
10323
10324 /*
10325 * Save the namespace import information.
10326 */
10327 if (WXS_IS_BUCKET_IMPMAIN(type)(((type) == 0) || ((type) == 1))) {
10328 relation->importNamespace = importNamespace;
10329 if (schemaLocation == NULL((void*)0)) {
10330 /*
10331 * No location; this is just an import of the namespace.
10332 * Note that we don't assign a bucket to the relation
10333 * in this case.
10334 */
10335 goto exit;
10336 }
10337 targetNamespace = importNamespace;
10338 }
10339
10340 /* Did we already fetch the doc? */
10341 if (bkt != NULL((void*)0)) {
10342 if ((WXS_IS_BUCKET_IMPMAIN(type)(((type) == 0) || ((type) == 1))) && (! bkt->imported)) {
10343 /*
10344 * We included/redefined and then try to import a schema,
10345 * but the new location provided for import was different.
10346 */
10347 if (schemaLocation == NULL((void*)0))
10348 schemaLocation = BAD_CAST(xmlChar *) "in_memory_buffer";
10349 if (!xmlStrEqual(schemaLocation,
10350 bkt->schemaLocation)) {
10351 xmlSchemaCustomErr(ACTXT_CAST(xmlSchemaAbstractCtxtPtr) pctxt, err,
10352 invokingNode, NULL((void*)0),
10353 "The schema document '%s' cannot be imported, since "
10354 "it was already included or redefined",
10355 schemaLocation, NULL((void*)0));
10356 goto exit;
10357 }
10358 } else if ((! WXS_IS_BUCKET_IMPMAIN(type)(((type) == 0) || ((type) == 1))) && (bkt->imported)) {
10359 /*
10360 * We imported and then try to include/redefine a schema,
10361 * but the new location provided for the include/redefine
10362 * was different.
10363 */
10364 if (schemaLocation == NULL((void*)0))
10365 schemaLocation = BAD_CAST(xmlChar *) "in_memory_buffer";
10366 if (!xmlStrEqual(schemaLocation,
10367 bkt->schemaLocation)) {
10368 xmlSchemaCustomErr(ACTXT_CAST(xmlSchemaAbstractCtxtPtr) pctxt, err,
10369 invokingNode, NULL((void*)0),
10370 "The schema document '%s' cannot be included or "
10371 "redefined, since it was already imported",
10372 schemaLocation, NULL((void*)0));
10373 goto exit;
10374 }
10375 }
10376 }
10377
10378 if (WXS_IS_BUCKET_IMPMAIN(type)(((type) == 0) || ((type) == 1))) {
10379 /*
10380 * Given that the schemaLocation [attribute] is only a hint, it is open
10381 * to applications to ignore all but the first <import> for a given
10382 * namespace, regardless of the `actual value` of schemaLocation, but
10383 * such a strategy risks missing useful information when new
10384 * schemaLocations are offered.
10385 *
10386 * We will use the first <import> that comes with a location.
10387 * Further <import>s *with* a location, will result in an error.
10388 * TODO: Better would be to just report a warning here, but
10389 * we'll try it this way until someone complains.
10390 *
10391 * Schema Document Location Strategy:
10392 * 3 Based on the namespace name, identify an existing schema document,
10393 * either as a resource which is an XML document or a <schema> element
10394 * information item, in some local schema repository;
10395 * 5 Attempt to resolve the namespace name to locate such a resource.
10396 *
10397 * NOTE: (3) and (5) are not supported.
10398 */
10399 if (bkt != NULL((void*)0)) {
10400 relation->bucket = bkt;
10401 goto exit;
10402 }
10403 bkt = xmlSchemaGetSchemaBucketByTNS(pctxt,
10404 importNamespace, 1);
10405
10406 if (bkt != NULL((void*)0)) {
10407 relation->bucket = bkt;
10408 if (bkt->schemaLocation == NULL((void*)0)) {
10409 /* First given location of the schema; load the doc. */
10410 bkt->schemaLocation = schemaLocation;
10411 } else {
10412 if (!xmlStrEqual(schemaLocation,
10413 bkt->schemaLocation)) {
10414 /*
10415 * Additional location given; just skip it.
10416 * URGENT TODO: We should report a warning here.
10417 * res = XML_SCHEMAP_SRC_IMPORT;
10418 */
10419 if (schemaLocation == NULL((void*)0))
10420 schemaLocation = BAD_CAST(xmlChar *) "in_memory_buffer";
10421
10422 xmlSchemaCustomWarning(ACTXT_CAST(xmlSchemaAbstractCtxtPtr) pctxt,
10423 XML_SCHEMAP_WARN_SKIP_SCHEMA,
10424 invokingNode, NULL((void*)0),
10425 "Skipping import of schema located at '%s' for the "
10426 "namespace '%s', since this namespace was already "
10427 "imported with the schema located at '%s'",
10428 schemaLocation, importNamespace, bkt->schemaLocation);
10429 }
10430 goto exit;
10431 }
10432 }
10433 /*
10434 * No bucket + first location: load the doc and create a
10435 * bucket.
10436 */
10437 } else {
10438 /* <include> and <redefine> */
10439 if (bkt != NULL((void*)0)) {
10440
10441 if ((bkt->origTargetNamespace == NULL((void*)0)) &&
10442 (bkt->targetNamespace != sourceTargetNamespace)) {
10443 xmlSchemaBucketPtr chamel;
10444
10445 /*
10446 * Chameleon include/redefine: skip loading only if it was
10447 * already build for the targetNamespace of the including
10448 * schema.
10449 */
10450 /*
10451 * URGENT TODO: If the schema is a chameleon-include then copy
10452 * the components into the including schema and modify the
10453 * targetNamespace of those components, do nothing otherwise.
10454 * NOTE: This is currently worked-around by compiling the
10455 * chameleon for every distinct including targetNamespace; thus
10456 * not performant at the moment.
10457 * TODO: Check when the namespace in wildcards for chameleons
10458 * needs to be converted: before we built wildcard intersections
10459 * or after.
10460 * Answer: after!
10461 */
10462 chamel = xmlSchemaGetChameleonSchemaBucket(pctxt,
10463 schemaLocation, sourceTargetNamespace);
10464 if (chamel != NULL((void*)0)) {
10465 /* A fitting chameleon was already parsed; NOP. */
10466 relation->bucket = chamel;
10467 goto exit;
10468 }
10469 /*
10470 * We need to parse the chameleon again for a different
10471 * targetNamespace.
10472 * CHAMELEON TODO: Optimize this by only parsing the
10473 * chameleon once, and then copying the components to
10474 * the new targetNamespace.
10475 */
10476 bkt = NULL((void*)0);
10477 } else {
10478 relation->bucket = bkt;
10479 goto exit;
10480 }
10481 }
10482 }
10483 if ((bkt != NULL((void*)0)) && (bkt->doc != NULL((void*)0))) {
10484 PERROR_INT("xmlSchemaAddSchemaDoc",xmlSchemaInternalErr((xmlSchemaAbstractCtxtPtr) pctxt, "xmlSchemaAddSchemaDoc"
, "trying to load a schema doc, but a doc is already " "assigned to the schema bucket"
);
10485 "trying to load a schema doc, but a doc is already "xmlSchemaInternalErr((xmlSchemaAbstractCtxtPtr) pctxt, "xmlSchemaAddSchemaDoc"
, "trying to load a schema doc, but a doc is already " "assigned to the schema bucket"
);
10486 "assigned to the schema bucket")xmlSchemaInternalErr((xmlSchemaAbstractCtxtPtr) pctxt, "xmlSchemaAddSchemaDoc"
, "trying to load a schema doc, but a doc is already " "assigned to the schema bucket"
);
;
10487 goto exit_failure;
10488 }
10489
10490doc_load:
10491 /*
10492 * Load the document.
10493 */
10494 if (schemaDoc != NULL((void*)0)) {
10495 doc = schemaDoc;
10496 /* Don' free this one, since it was provided by the caller. */
10497 preserveDoc = 1;
10498 /* TODO: Does the context or the doc hold the location? */
10499 if (schemaDoc->URL != NULL((void*)0))
10500 schemaLocation = xmlDictLookup(pctxt->dict,
10501 schemaDoc->URL, -1);
10502 else
10503 schemaLocation = BAD_CAST(xmlChar *) "in_memory_buffer";
10504 } else if ((schemaLocation != NULL((void*)0)) || (schemaBuffer != NULL((void*)0))) {
10505 xmlParserCtxtPtr parserCtxt;
10506
10507 parserCtxt = xmlNewParserCtxt();
10508 if (parserCtxt == NULL((void*)0)) {
10509 xmlSchemaPErrMemory(NULL((void*)0), "xmlSchemaGetDoc, "
10510 "allocating a parser context", NULL((void*)0));
10511 goto exit_failure;
10512 }
10513 if ((pctxt->dict != NULL((void*)0)) && (parserCtxt->dict != NULL((void*)0))) {
10514 /*
10515 * TODO: Do we have to burden the schema parser dict with all
10516 * the content of the schema doc?
10517 */
10518 xmlDictFree(parserCtxt->dict);
10519 parserCtxt->dict = pctxt->dict;
10520 xmlDictReference(parserCtxt->dict);
10521 }
10522 if (schemaLocation != NULL((void*)0)) {
10523 /* Parse from file. */
10524 doc = xmlCtxtReadFile(parserCtxt, (const char *) schemaLocation,
10525 NULL((void*)0), SCHEMAS_PARSE_OPTIONSXML_PARSE_NOENT);
10526 } else if (schemaBuffer != NULL((void*)0)) {
10527 /* Parse from memory buffer. */
10528 doc = xmlCtxtReadMemory(parserCtxt, schemaBuffer, schemaBufferLen,
10529 NULL((void*)0), NULL((void*)0), SCHEMAS_PARSE_OPTIONSXML_PARSE_NOENT);
10530 schemaLocation = BAD_CAST(xmlChar *) "in_memory_buffer";
10531 if (doc != NULL((void*)0))
10532 doc->URL = xmlStrdup(schemaLocation);
10533 }
10534 /*
10535 * For <import>:
10536 * 2.1 The referent is (a fragment of) a resource which is an
10537 * XML document (see clause 1.1), which in turn corresponds to
10538 * a <schema> element information item in a well-formed information
10539 * set, which in turn corresponds to a valid schema.
10540 * TODO: (2.1) fragments of XML documents are not supported.
10541 *
10542 * 2.2 The referent is a <schema> element information item in
10543 * a well-formed information set, which in turn corresponds
10544 * to a valid schema.
10545 * TODO: (2.2) is not supported.
10546 */
10547 if (doc == NULL((void*)0)) {
10548 const xmlError *lerr;
10549 lerr = xmlGetLastError();
10550 /*
10551 * Check if this a parser error, or if the document could
10552 * just not be located.
10553 * TODO: Try to find specific error codes to react only on
10554 * localisation failures.
10555 */
10556 if ((lerr == NULL((void*)0)) || (lerr->domain != XML_FROM_IO)) {
10557 /*
10558 * We assume a parser error here.
10559 */
10560 located = 1;
10561 /* TODO: Error code ?? */
10562 res = XML_SCHEMAP_SRC_IMPORT_2_1;
10563 xmlSchemaCustomErr(ACTXT_CAST(xmlSchemaAbstractCtxtPtr) pctxt, res,
10564 invokingNode, NULL((void*)0),
10565 "Failed to parse the XML resource '%s'",
10566 schemaLocation, NULL((void*)0));
10567 }
10568 }
10569 xmlFreeParserCtxt(parserCtxt);
10570 if ((doc == NULL((void*)0)) && located)
10571 goto exit_error;
10572 } else {
10573 xmlSchemaPErr(pctxt, NULL((void*)0),
10574 XML_SCHEMAP_NOTHING_TO_PARSE,
10575 "No information for parsing was provided with the "
10576 "given schema parser context.\n",
10577 NULL((void*)0), NULL((void*)0));
10578 goto exit_failure;
10579 }
10580 /*
10581 * Preprocess the document.
10582 */
10583 if (doc != NULL((void*)0)) {
10584 xmlNodePtr docElem = NULL((void*)0);
10585
10586 located = 1;
10587 docElem = xmlDocGetRootElement(doc);
10588 if (docElem == NULL((void*)0)) {
10589 xmlSchemaCustomErr(ACTXT_CAST(xmlSchemaAbstractCtxtPtr) pctxt, XML_SCHEMAP_NOROOT,
10590 invokingNode, NULL((void*)0),
10591 "The document '%s' has no document element",
10592 schemaLocation, NULL((void*)0));
10593 goto exit_error;
10594 }
10595 /*
10596 * Remove all the blank text nodes.
10597 */
10598 xmlSchemaCleanupDoc(pctxt, docElem);
10599 /*
10600 * Check the schema's top level element.
10601 */
10602 if (!IS_SCHEMA(docElem, "schema")((docElem != ((void*)0)) && (docElem->ns != ((void
*)0)) && (xmlStrEqual(docElem->name, (const xmlChar
*) "schema")) && (xmlStrEqual(docElem->ns->href
, xmlSchemaNs)))
) {
10603 xmlSchemaCustomErr(ACTXT_CAST(xmlSchemaAbstractCtxtPtr) pctxt, XML_SCHEMAP_NOT_SCHEMA,
10604 invokingNode, NULL((void*)0),
10605 "The XML document '%s' is not a schema document",
10606 schemaLocation, NULL((void*)0));
10607 goto exit_error;
10608 }
10609 /*
10610 * Note that we don't apply a type check for the
10611 * targetNamespace value here.
10612 */
10613 targetNamespace = xmlSchemaGetProp(pctxt, docElem,
10614 "targetNamespace");
10615 }
10616
10617/* after_doc_loading: */
10618 if ((bkt == NULL((void*)0)) && located) {
10619 /* Only create a bucket if the schema was located. */
10620 bkt = xmlSchemaBucketCreate(pctxt, type,
10621 targetNamespace);
10622 if (bkt == NULL((void*)0))
10623 goto exit_failure;
10624 }
10625 if (bkt != NULL((void*)0)) {
10626 bkt->schemaLocation = schemaLocation;
10627 bkt->located = located;
10628 if (doc != NULL((void*)0)) {
10629 bkt->doc = doc;
10630 bkt->targetNamespace = targetNamespace;
10631 bkt->origTargetNamespace = targetNamespace;
10632 if (preserveDoc)
10633 bkt->preserveDoc = 1;
10634 }
10635 if (WXS_IS_BUCKET_IMPMAIN(type)(((type) == 0) || ((type) == 1)))
10636 bkt->imported++;
10637 /*
10638 * Add it to the graph of schemas.
10639 */
10640 if (relation != NULL((void*)0))
10641 relation->bucket = bkt;
10642 }
10643
10644exit:
10645 /*
10646 * Return the bucket explicitly; this is needed for the
10647 * main schema.
10648 */
10649 if (bucket != NULL((void*)0))
10650 *bucket = bkt;
10651 return (0);
10652
10653exit_error:
10654 if ((doc != NULL((void*)0)) && (! preserveDoc)) {
10655 xmlFreeDoc(doc);
10656 if (bkt != NULL((void*)0))
10657 bkt->doc = NULL((void*)0);
10658 }
10659 return(pctxt->err);
10660
10661exit_failure:
10662 if ((doc != NULL((void*)0)) && (! preserveDoc)) {
10663 xmlFreeDoc(doc);
10664 if (bkt != NULL((void*)0))
10665 bkt->doc = NULL((void*)0);
10666 }
10667 return (-1);
10668}
10669
10670/**
10671 * xmlSchemaParseImport:
10672 * @ctxt: a schema validation context
10673 * @schema: the schema being built
10674 * @node: a subtree containing XML Schema information
10675 *
10676 * parse a XML schema Import definition
10677 * *WARNING* this interface is highly subject to change
10678 *
10679 * Returns 0 in case of success, a positive error code if
10680 * not valid and -1 in case of an internal error.
10681 */
10682static int
10683xmlSchemaParseImport(xmlSchemaParserCtxtPtr pctxt, xmlSchemaPtr schema,
10684 xmlNodePtr node)
10685{
10686 xmlNodePtr child;
10687 const xmlChar *namespaceName = NULL((void*)0), *schemaLocation = NULL((void*)0);
10688 const xmlChar *thisTargetNamespace;
10689 xmlAttrPtr attr;
10690 int ret = 0;
10691 xmlSchemaBucketPtr bucket = NULL((void*)0);
10692
10693 if ((pctxt == NULL((void*)0)) || (schema == NULL((void*)0)) || (node == NULL((void*)0)))
10694 return (-1);
10695
10696 /*
10697 * Check for illegal attributes.
10698 */
10699 attr = node->properties;
10700 while (attr != NULL((void*)0)) {
10701 if (attr->ns == NULL((void*)0)) {
10702 if ((!xmlStrEqual(attr->name, BAD_CAST(xmlChar *) "id")) &&
10703 (!xmlStrEqual(attr->name, BAD_CAST(xmlChar *) "namespace")) &&
10704 (!xmlStrEqual(attr->name, BAD_CAST(xmlChar *) "schemaLocation"))) {
10705 xmlSchemaPIllegalAttrErr(pctxt,
10706 XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL((void*)0), attr);
10707 }
10708 } else if (xmlStrEqual(attr->ns->href, xmlSchemaNs)) {
10709 xmlSchemaPIllegalAttrErr(pctxt,
10710 XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL((void*)0), attr);
10711 }
10712 attr = attr->next;
10713 }
10714 /*
10715 * Extract and validate attributes.
10716 */
10717 if (xmlSchemaPValAttr(pctxt, NULL((void*)0), node,
10718 "namespace", xmlSchemaGetBuiltInType(XML_SCHEMAS_ANYURI),
10719 &namespaceName) != 0) {
10720 xmlSchemaPSimpleTypeErr(pctxt,
10721 XML_SCHEMAP_S4S_ATTR_INVALID_VALUE,
10722 NULL((void*)0), node,
10723 xmlSchemaGetBuiltInType(XML_SCHEMAS_ANYURI),
10724 NULL((void*)0), namespaceName, NULL((void*)0), NULL((void*)0), NULL((void*)0));
10725 return (pctxt->err);
10726 }
10727
10728 if (xmlSchemaPValAttr(pctxt, NULL((void*)0), node,
10729 "schemaLocation", xmlSchemaGetBuiltInType(XML_SCHEMAS_ANYURI),
10730 &schemaLocation) != 0) {
10731 xmlSchemaPSimpleTypeErr(pctxt,
10732 XML_SCHEMAP_S4S_ATTR_INVALID_VALUE,
10733 NULL((void*)0), node,
10734 xmlSchemaGetBuiltInType(XML_SCHEMAS_ANYURI),
10735 NULL((void*)0), schemaLocation, NULL((void*)0), NULL((void*)0), NULL((void*)0));
10736 return (pctxt->err);
10737 }
10738 /*
10739 * And now for the children...
10740 */
10741 child = node->children;
10742 if (IS_SCHEMA(child, "annotation")((child != ((void*)0)) && (child->ns != ((void*)0)
) && (xmlStrEqual(child->name, (const xmlChar *) "annotation"
)) && (xmlStrEqual(child->ns->href, xmlSchemaNs
)))
) {
10743 /*
10744 * the annotation here is simply discarded ...
10745 * TODO: really?
10746 */
10747 child = child->next;
10748 }
10749 if (child != NULL((void*)0)) {
10750 xmlSchemaPContentErr(pctxt,
10751 XML_SCHEMAP_S4S_ELEM_NOT_ALLOWED,
10752 NULL((void*)0), node, child, NULL((void*)0),
10753 "(annotation?)");
10754 }
10755 /*
10756 * Apply additional constraints.
10757 *
10758 * Note that it is important to use the original @targetNamespace
10759 * (or none at all), to rule out imports of schemas _with_ a
10760 * @targetNamespace if the importing schema is a chameleon schema
10761 * (with no @targetNamespace).
10762 */
10763 thisTargetNamespace = WXS_BUCKET(pctxt)((pctxt))->constructor->bucket->origTargetNamespace;
10764 if (namespaceName != NULL((void*)0)) {
10765 /*
10766 * 1.1 If the namespace [attribute] is present, then its `actual value`
10767 * must not match the `actual value` of the enclosing <schema>'s
10768 * targetNamespace [attribute].
10769 */
10770 if (xmlStrEqual(thisTargetNamespace, namespaceName)) {
10771 xmlSchemaPCustomErr(pctxt,
10772 XML_SCHEMAP_SRC_IMPORT_1_1,
10773 NULL((void*)0), node,
10774 "The value of the attribute 'namespace' must not match "
10775 "the target namespace '%s' of the importing schema",
10776 thisTargetNamespace);
10777 return (pctxt->err);
10778 }
10779 } else {
10780 /*
10781 * 1.2 If the namespace [attribute] is not present, then the enclosing
10782 * <schema> must have a targetNamespace [attribute].
10783 */
10784 if (thisTargetNamespace == NULL((void*)0)) {
10785 xmlSchemaPCustomErr(pctxt,
10786 XML_SCHEMAP_SRC_IMPORT_1_2,
10787 NULL((void*)0), node,
10788 "The attribute 'namespace' must be existent if "
10789 "the importing schema has no target namespace",
10790 NULL((void*)0));
10791 return (pctxt->err);
10792 }
10793 }
10794 /*
10795 * Locate and acquire the schema document.
10796 */
10797 if (schemaLocation != NULL((void*)0))
10798 schemaLocation = xmlSchemaBuildAbsoluteURI(pctxt->dict,
10799 schemaLocation, node);
10800 ret = xmlSchemaAddSchemaDoc(pctxt, XML_SCHEMA_SCHEMA_IMPORT1,
10801 schemaLocation, NULL((void*)0), NULL((void*)0), 0, node, thisTargetNamespace,
10802 namespaceName, &bucket);
10803
10804 if (ret != 0)
10805 return(ret);
10806
10807 /*
10808 * For <import>: "It is *not* an error for the application
10809 * schema reference strategy to fail."
10810 * So just don't parse if no schema document was found.
10811 * Note that we will get no bucket if the schema could not be
10812 * located or if there was no schemaLocation.
10813 */
10814 if ((bucket == NULL((void*)0)) && (schemaLocation != NULL((void*)0))) {
10815 xmlSchemaCustomWarning(ACTXT_CAST(xmlSchemaAbstractCtxtPtr) pctxt,
10816 XML_SCHEMAP_WARN_UNLOCATED_SCHEMA,
10817 node, NULL((void*)0),
10818 "Failed to locate a schema at location '%s'. "
10819 "Skipping the import", schemaLocation, NULL((void*)0), NULL((void*)0));
10820 }
10821
10822 if ((bucket != NULL((void*)0)) && CAN_PARSE_SCHEMA(bucket)(((bucket)->doc != ((void*)0)) && ((bucket)->parsed
== 0))
) {
10823 ret = xmlSchemaParseNewDoc(pctxt, schema, bucket);
10824 }
10825
10826 return (ret);
10827}
10828
10829static int
10830xmlSchemaParseIncludeOrRedefineAttrs(xmlSchemaParserCtxtPtr pctxt,
10831 xmlSchemaPtr schema,
10832 xmlNodePtr node,
10833 xmlChar **schemaLocation,
10834 int type)
10835{
10836 xmlAttrPtr attr;
10837
10838 if ((pctxt == NULL((void*)0)) || (schema == NULL((void*)0)) || (node == NULL((void*)0)) ||
10839 (schemaLocation == NULL((void*)0)))
10840 return (-1);
10841
10842 *schemaLocation = NULL((void*)0);
10843 /*
10844 * Check for illegal attributes.
10845 * Applies for both <include> and <redefine>.
10846 */
10847 attr = node->properties;
10848 while (attr != NULL((void*)0)) {
10849 if (attr->ns == NULL((void*)0)) {
10850 if ((!xmlStrEqual(attr->name, BAD_CAST(xmlChar *) "id")) &&
10851 (!xmlStrEqual(attr->name, BAD_CAST(xmlChar *) "schemaLocation"))) {
10852 xmlSchemaPIllegalAttrErr(pctxt,
10853 XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL((void*)0), attr);
10854 }
10855 } else if (xmlStrEqual(attr->ns->href, xmlSchemaNs)) {
10856 xmlSchemaPIllegalAttrErr(pctxt,
10857 XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL((void*)0), attr);
10858 }
10859 attr = attr->next;
10860 }
10861 xmlSchemaPValAttrID(pctxt, node, BAD_CAST(xmlChar *) "id");
10862 /*
10863 * Preliminary step, extract the URI-Reference and make an URI
10864 * from the base.
10865 */
10866 /*
10867 * Attribute "schemaLocation" is mandatory.
10868 */
10869 attr = xmlSchemaGetPropNode(node, "schemaLocation");
10870 if (attr != NULL((void*)0)) {
10871 xmlChar *base = NULL((void*)0);
10872 xmlChar *uri = NULL((void*)0);
10873
10874 if (xmlSchemaPValAttrNode(pctxt, NULL((void*)0), attr,
10875 xmlSchemaGetBuiltInType(XML_SCHEMAS_ANYURI),
10876 (const xmlChar **) schemaLocation) != 0)
10877 goto exit_error;
10878 base = xmlNodeGetBase(node->doc, node);
10879 if (base == NULL((void*)0)) {
10880 uri = xmlBuildURI(*schemaLocation, node->doc->URL);
10881 } else {
10882 uri = xmlBuildURI(*schemaLocation, base);
10883 xmlFree(base);
10884 }
10885 if (uri == NULL((void*)0)) {
10886 PERROR_INT("xmlSchemaParseIncludeOrRedefine",xmlSchemaInternalErr((xmlSchemaAbstractCtxtPtr) pctxt, "xmlSchemaParseIncludeOrRedefine"
, "could not build an URI from the schemaLocation");
10887 "could not build an URI from the schemaLocation")xmlSchemaInternalErr((xmlSchemaAbstractCtxtPtr) pctxt, "xmlSchemaParseIncludeOrRedefine"
, "could not build an URI from the schemaLocation");
10888 goto exit_failure;
10889 }
10890 (*schemaLocation) = (xmlChar *) xmlDictLookup(pctxt->dict, uri, -1);
10891 xmlFree(uri);
10892 } else {
10893 xmlSchemaPMissingAttrErr(pctxt,
10894 XML_SCHEMAP_S4S_ATTR_MISSING,
10895 NULL((void*)0), node, "schemaLocation", NULL((void*)0));
10896 goto exit_error;
10897 }
10898 /*
10899 * Report self-inclusion and self-redefinition.
10900 */
10901 if (xmlStrEqual(*schemaLocation, pctxt->URL)) {
10902 if (type == XML_SCHEMA_SCHEMA_REDEFINE3) {
10903 xmlSchemaPCustomErr(pctxt,
10904 XML_SCHEMAP_SRC_REDEFINE,
10905 NULL((void*)0), node,
10906 "The schema document '%s' cannot redefine itself.",
10907 *schemaLocation);
10908 } else {
10909 xmlSchemaPCustomErr(pctxt,
10910 XML_SCHEMAP_SRC_INCLUDE,
10911 NULL((void*)0), node,
10912 "The schema document '%s' cannot include itself.",
10913 *schemaLocation);
10914 }
10915 goto exit_error;
10916 }
10917
10918 return(0);
10919exit_error:
10920 return(pctxt->err);
10921exit_failure:
10922 return(-1);
10923}
10924
10925static int
10926xmlSchemaParseIncludeOrRedefine(xmlSchemaParserCtxtPtr pctxt,
10927 xmlSchemaPtr schema,
10928 xmlNodePtr node,
10929 int type)
10930{
10931 xmlNodePtr child = NULL((void*)0);
10932 const xmlChar *schemaLocation = NULL((void*)0);
10933 int res = 0; /* hasRedefinitions = 0 */
10934 int isChameleon = 0, wasChameleon = 0;
10935 xmlSchemaBucketPtr bucket = NULL((void*)0);
10936
10937 if ((pctxt == NULL((void*)0)) || (schema == NULL((void*)0)) || (node == NULL((void*)0)))
10938 return (-1);
10939
10940 /*
10941 * Parse attributes. Note that the returned schemaLocation will
10942 * be already converted to an absolute URI.
10943 */
10944 res = xmlSchemaParseIncludeOrRedefineAttrs(pctxt, schema,
10945 node, (xmlChar **) (&schemaLocation), type);
10946 if (res != 0)
10947 return(res);
10948 /*
10949 * Load and add the schema document.
10950 */
10951 res = xmlSchemaAddSchemaDoc(pctxt, type, schemaLocation, NULL((void*)0),
10952 NULL((void*)0), 0, node, pctxt->targetNamespace, NULL((void*)0), &bucket);
10953 if (res != 0)
10954 return(res);
10955 /*
10956 * If we get no schema bucket back, then this means that the schema
10957 * document could not be located or was broken XML or was not
10958 * a schema document.
10959 */
10960 if ((bucket == NULL((void*)0)) || (bucket->doc == NULL((void*)0))) {
10961 if (type == XML_SCHEMA_SCHEMA_INCLUDE2) {
10962 /*
10963 * WARNING for <include>:
10964 * We will raise an error if the schema cannot be located
10965 * for inclusions, since the that was the feedback from the
10966 * schema people. I.e. the following spec piece will *not* be
10967 * satisfied:
10968 * SPEC src-include: "It is not an error for the `actual value` of the
10969 * schemaLocation [attribute] to fail to resolve it all, in which
10970 * case no corresponding inclusion is performed.
10971 * So do we need a warning report here?"
10972 */
10973 res = XML_SCHEMAP_SRC_INCLUDE;
10974 xmlSchemaCustomErr(ACTXT_CAST(xmlSchemaAbstractCtxtPtr) pctxt, res,
10975 node, NULL((void*)0),
10976 "Failed to load the document '%s' for inclusion",
10977 schemaLocation, NULL((void*)0));
10978 } else {
10979 /*
10980 * NOTE: This was changed to raise an error even if no redefinitions
10981 * are specified.
10982 *
10983 * SPEC src-redefine (1)
10984 * "If there are any element information items among the [children]
10985 * other than <annotation> then the `actual value` of the
10986 * schemaLocation [attribute] must successfully resolve."
10987 * TODO: Ask the WG if a the location has always to resolve
10988 * here as well!
10989 */
10990 res = XML_SCHEMAP_SRC_REDEFINE;
10991 xmlSchemaCustomErr(ACTXT_CAST(xmlSchemaAbstractCtxtPtr) pctxt, res,
10992 node, NULL((void*)0),
10993 "Failed to load the document '%s' for redefinition",
10994 schemaLocation, NULL((void*)0));
10995 }
10996 } else {
10997 /*
10998 * Check targetNamespace sanity before parsing the new schema.
10999 * TODO: Note that we won't check further content if the
11000 * targetNamespace was bad.
11001 */
11002 if (bucket->origTargetNamespace != NULL((void*)0)) {
11003 /*
11004 * SPEC src-include (2.1)
11005 * "SII has a targetNamespace [attribute], and its `actual
11006 * value` is identical to the `actual value` of the targetNamespace
11007 * [attribute] of SII' (which must have such an [attribute])."
11008 */
11009 if (pctxt->targetNamespace == NULL((void*)0)) {
11010 xmlSchemaCustomErr(ACTXT_CAST(xmlSchemaAbstractCtxtPtr) pctxt,
11011 XML_SCHEMAP_SRC_INCLUDE,
11012 node, NULL((void*)0),
11013 "The target namespace of the included/redefined schema "
11014 "'%s' has to be absent, since the including/redefining "
11015 "schema has no target namespace",
11016 schemaLocation, NULL((void*)0));
11017 goto exit_error;
11018 } else if (!xmlStrEqual(bucket->origTargetNamespace,
11019 pctxt->targetNamespace)) {
11020 /* TODO: Change error function. */
11021 xmlSchemaPCustomErrExt(pctxt,
11022 XML_SCHEMAP_SRC_INCLUDE,
11023 NULL((void*)0), node,
11024 "The target namespace '%s' of the included/redefined "
11025 "schema '%s' differs from '%s' of the "
11026 "including/redefining schema",
11027 bucket->origTargetNamespace, schemaLocation,
11028 pctxt->targetNamespace);
11029 goto exit_error;
11030 }
11031 } else if (pctxt->targetNamespace != NULL((void*)0)) {
11032 /*
11033 * Chameleons: the original target namespace will
11034 * differ from the resulting namespace.
11035 */
11036 isChameleon = 1;
11037 bucket->targetNamespace = pctxt->targetNamespace;
11038 }
11039 }
11040 /*
11041 * Parse the schema.
11042 */
11043 if (bucket && (!bucket->parsed) && (bucket->doc != NULL((void*)0))) {
11044 if (isChameleon) {
11045 /* TODO: Get rid of this flag on the schema itself. */
11046 if ((schema->flags & XML_SCHEMAS_INCLUDING_CONVERT_NS1 << 9) == 0) {
11047 schema->flags |= XML_SCHEMAS_INCLUDING_CONVERT_NS1 << 9;
11048 } else
11049 wasChameleon = 1;
11050 }
11051 xmlSchemaParseNewDoc(pctxt, schema, bucket);
11052 /* Restore chameleon flag. */
11053 if (isChameleon && (!wasChameleon))
11054 schema->flags ^= XML_SCHEMAS_INCLUDING_CONVERT_NS1 << 9;
11055 }
11056 /*
11057 * And now for the children...
11058 */
11059 child = node->children;
11060 if (type == XML_SCHEMA_SCHEMA_REDEFINE3) {
11061 /*
11062 * Parse (simpleType | complexType | group | attributeGroup))*
11063 */
11064 pctxt->redefined = bucket;
11065 /*
11066 * How to proceed if the redefined schema was not located?
11067 */
11068 pctxt->isRedefine = 1;
11069 while (IS_SCHEMA(child, "annotation")((child != ((void*)0)) && (child->ns != ((void*)0)
) && (xmlStrEqual(child->name, (const xmlChar *) "annotation"
)) && (xmlStrEqual(child->ns->href, xmlSchemaNs
)))
||
11070 IS_SCHEMA(child, "simpleType")((child != ((void*)0)) && (child->ns != ((void*)0)
) && (xmlStrEqual(child->name, (const xmlChar *) "simpleType"
)) && (xmlStrEqual(child->ns->href, xmlSchemaNs
)))
||
11071 IS_SCHEMA(child, "complexType")((child != ((void*)0)) && (child->ns != ((void*)0)
) && (xmlStrEqual(child->name, (const xmlChar *) "complexType"
)) && (xmlStrEqual(child->ns->href, xmlSchemaNs
)))
||
11072 IS_SCHEMA(child, "group")((child != ((void*)0)) && (child->ns != ((void*)0)
) && (xmlStrEqual(child->name, (const xmlChar *) "group"
)) && (xmlStrEqual(child->ns->href, xmlSchemaNs
)))
||
11073 IS_SCHEMA(child, "attributeGroup")((child != ((void*)0)) && (child->ns != ((void*)0)
) && (xmlStrEqual(child->name, (const xmlChar *) "attributeGroup"
)) && (xmlStrEqual(child->ns->href, xmlSchemaNs
)))
) {
11074 if (IS_SCHEMA(child, "annotation")((child != ((void*)0)) && (child->ns != ((void*)0)
) && (xmlStrEqual(child->name, (const xmlChar *) "annotation"
)) && (xmlStrEqual(child->ns->href, xmlSchemaNs
)))
) {
11075 /*
11076 * TODO: discard or not?
11077 */
11078 } else if (IS_SCHEMA(child, "simpleType")((child != ((void*)0)) && (child->ns != ((void*)0)
) && (xmlStrEqual(child->name, (const xmlChar *) "simpleType"
)) && (xmlStrEqual(child->ns->href, xmlSchemaNs
)))
) {
11079 xmlSchemaParseSimpleType(pctxt, schema, child, 1);
11080 } else if (IS_SCHEMA(child, "complexType")((child != ((void*)0)) && (child->ns != ((void*)0)
) && (xmlStrEqual(child->name, (const xmlChar *) "complexType"
)) && (xmlStrEqual(child->ns->href, xmlSchemaNs
)))
) {
11081 xmlSchemaParseComplexType(pctxt, schema, child, 1);
11082 /* hasRedefinitions = 1; */
11083 } else if (IS_SCHEMA(child, "group")((child != ((void*)0)) && (child->ns != ((void*)0)
) && (xmlStrEqual(child->name, (const xmlChar *) "group"
)) && (xmlStrEqual(child->ns->href, xmlSchemaNs
)))
) {
11084 /* hasRedefinitions = 1; */
11085 xmlSchemaParseModelGroupDefinition(pctxt,
11086 schema, child);
11087 } else if (IS_SCHEMA(child, "attributeGroup")((child != ((void*)0)) && (child->ns != ((void*)0)
) && (xmlStrEqual(child->name, (const xmlChar *) "attributeGroup"
)) && (xmlStrEqual(child->ns->href, xmlSchemaNs
)))
) {
11088 /* hasRedefinitions = 1; */
11089 xmlSchemaParseAttributeGroupDefinition(pctxt, schema,
11090 child);
11091 }
11092 child = child->next;
11093 }
11094 pctxt->redefined = NULL((void*)0);
11095 pctxt->isRedefine = 0;
11096 } else {
11097 if (IS_SCHEMA(child, "annotation")((child != ((void*)0)) && (child->ns != ((void*)0)
) && (xmlStrEqual(child->name, (const xmlChar *) "annotation"
)) && (xmlStrEqual(child->ns->href, xmlSchemaNs
)))
) {
11098 /*
11099 * TODO: discard or not?
11100 */
11101 child = child->next;
11102 }
11103 }
11104 if (child != NULL((void*)0)) {
11105 res = XML_SCHEMAP_S4S_ELEM_NOT_ALLOWED;
11106 if (type == XML_SCHEMA_SCHEMA_REDEFINE3) {
11107 xmlSchemaPContentErr(pctxt, res,
11108 NULL((void*)0), node, child, NULL((void*)0),
11109 "(annotation | (simpleType | complexType | group | attributeGroup))*");
11110 } else {
11111 xmlSchemaPContentErr(pctxt, res,
11112 NULL((void*)0), node, child, NULL((void*)0),
11113 "(annotation?)");
11114 }
11115 }
11116 return(res);
11117
11118exit_error:
11119 return(pctxt->err);
11120}
11121
11122static int
11123xmlSchemaParseRedefine(xmlSchemaParserCtxtPtr pctxt, xmlSchemaPtr schema,
11124 xmlNodePtr node)
11125{
11126 int res;
11127#ifndef ENABLE_REDEFINE
11128 TODO(*__xmlGenericError())((*__xmlGenericErrorContext()), "Unimplemented block at %s:%d\n"
, "xmlschemas.c", 11128);
11129 return(0);
11130#endif
11131 res = xmlSchemaParseIncludeOrRedefine(pctxt, schema, node,
11132 XML_SCHEMA_SCHEMA_REDEFINE3);
11133 if (res != 0)
11134 return(res);
11135 return(0);
11136}
11137
11138static int
11139xmlSchemaParseInclude(xmlSchemaParserCtxtPtr pctxt, xmlSchemaPtr schema,
11140 xmlNodePtr node)
11141{
11142 int res;
11143
11144 res = xmlSchemaParseIncludeOrRedefine(pctxt, schema, node,
11145 XML_SCHEMA_SCHEMA_INCLUDE2);
11146 if (res != 0)
11147 return(res);
11148 return(0);
11149}
11150
11151/**
11152 * xmlSchemaParseModelGroup:
11153 * @ctxt: a schema validation context
11154 * @schema: the schema being built
11155 * @node: a subtree containing XML Schema information
11156 * @type: the "compositor" type
11157 * @particleNeeded: if a a model group with a particle
11158 *
11159 * parse a XML schema Sequence definition.
11160 * Applies parts of:
11161 * Schema Representation Constraint:
11162 * Redefinition Constraints and Semantics (src-redefine)
11163 * (6.1), (6.1.1), (6.1.2)
11164 *
11165 * Schema Component Constraint:
11166 * All Group Limited (cos-all-limited) (2)
11167 * TODO: Actually this should go to component-level checks,
11168 * but is done here due to performance. Move it to an other layer
11169 * is schema construction via an API is implemented.
11170 *
11171 * *WARNING* this interface is highly subject to change
11172 *
11173 * Returns -1 in case of error, 0 if the declaration is improper and
11174 * 1 in case of success.
11175 */
11176static xmlSchemaTreeItemPtr
11177xmlSchemaParseModelGroup(xmlSchemaParserCtxtPtr ctxt, xmlSchemaPtr schema,
11178 xmlNodePtr node, xmlSchemaTypeType type,
11179 int withParticle)
11180{
11181 xmlSchemaModelGroupPtr item;
11182 xmlSchemaParticlePtr particle = NULL((void*)0);
11183 xmlNodePtr child = NULL((void*)0);
11184 xmlAttrPtr attr;
11185 int min = 1, max = 1, isElemRef, hasRefs = 0;
11186
11187 if ((ctxt == NULL((void*)0)) || (schema == NULL((void*)0)) || (node == NULL((void*)0)))
11188 return (NULL((void*)0));
11189 /*
11190 * Create a model group with the given compositor.
11191 */
11192 item = xmlSchemaAddModelGroup(ctxt, schema, type, node);
11193 if (item == NULL((void*)0))
11194 return (NULL((void*)0));
11195
11196 if (withParticle) {
11197 if (type == XML_SCHEMA_TYPE_ALL) {
11198 min = xmlGetMinOccurs(ctxt, node, 0, 1, 1, "(0 | 1)");
11199 max = xmlGetMaxOccurs(ctxt, node, 1, 1, 1, "1");
11200 } else {
11201 /* choice + sequence */
11202 min = xmlGetMinOccurs(ctxt, node, 0, -1, 1, "xs:nonNegativeInteger");
11203 max = xmlGetMaxOccurs(ctxt, node, 0, UNBOUNDED(1 << 30), 1,
11204 "(xs:nonNegativeInteger | unbounded)");
11205 }
11206 xmlSchemaPCheckParticleCorrect_2(ctxt, NULL((void*)0), node, min, max);
11207 /*
11208 * Create a particle
11209 */
11210 particle = xmlSchemaAddParticle(ctxt, node, min, max);
11211 if (particle == NULL((void*)0))
11212 return (NULL((void*)0));
11213 particle->children = (xmlSchemaTreeItemPtr) item;
11214 /*
11215 * Check for illegal attributes.
11216 */
11217 attr = node->properties;
11218 while (attr != NULL((void*)0)) {
11219 if (attr->ns == NULL((void*)0)) {
11220 if ((!xmlStrEqual(attr->name, BAD_CAST(xmlChar *) "id")) &&
11221 (!xmlStrEqual(attr->name, BAD_CAST(xmlChar *) "maxOccurs")) &&
11222 (!xmlStrEqual(attr->name, BAD_CAST(xmlChar *) "minOccurs"))) {
11223 xmlSchemaPIllegalAttrErr(ctxt,
11224 XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL((void*)0), attr);
11225 }
11226 } else if (xmlStrEqual(attr->ns->href, xmlSchemaNs)) {
11227 xmlSchemaPIllegalAttrErr(ctxt,
11228 XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL((void*)0), attr);
11229 }
11230 attr = attr->next;
11231 }
11232 } else {
11233 /*
11234 * Check for illegal attributes.
11235 */
11236 attr = node->properties;
11237 while (attr != NULL((void*)0)) {
11238 if (attr->ns == NULL((void*)0)) {
11239 if (!xmlStrEqual(attr->name, BAD_CAST(xmlChar *) "id")) {
11240 xmlSchemaPIllegalAttrErr(ctxt,
11241 XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL((void*)0), attr);
11242 }
11243 } else if (xmlStrEqual(attr->ns->href, xmlSchemaNs)) {
11244 xmlSchemaPIllegalAttrErr(ctxt,
11245 XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL((void*)0), attr);
11246 }
11247 attr = attr->next;
11248 }
11249 }
11250
11251 /*
11252 * Extract and validate attributes.
11253 */
11254 xmlSchemaPValAttrID(ctxt, node, BAD_CAST(xmlChar *) "id");
11255 /*
11256 * And now for the children...
11257 */
11258 child = node->children;
11259 if (IS_SCHEMA(child, "annotation")((child != ((void*)0)) && (child->ns != ((void*)0)
) && (xmlStrEqual(child->name, (const xmlChar *) "annotation"
)) && (xmlStrEqual(child->ns->href, xmlSchemaNs
)))
) {
11260 item->annot = xmlSchemaParseAnnotation(ctxt, child, 1);
11261 child = child->next;
11262 }
11263 if (type == XML_SCHEMA_TYPE_ALL) {
11264 xmlSchemaParticlePtr part, last = NULL((void*)0);
11265
11266 while (IS_SCHEMA(child, "element")((child != ((void*)0)) && (child->ns != ((void*)0)
) && (xmlStrEqual(child->name, (const xmlChar *) "element"
)) && (xmlStrEqual(child->ns->href, xmlSchemaNs
)))
) {
11267 part = (xmlSchemaParticlePtr) xmlSchemaParseElement(ctxt,
11268 schema, child, &isElemRef, 0);
11269 /*
11270 * SPEC cos-all-limited (2)
11271 * "The {max occurs} of all the particles in the {particles}
11272 * of the ('all') group must be 0 or 1.
11273 */
11274 if (part != NULL((void*)0)) {
11275 if (isElemRef)
11276 hasRefs++;
11277 if (part->minOccurs > 1) {
11278 xmlSchemaPCustomErr(ctxt,
11279 XML_SCHEMAP_COS_ALL_LIMITED,
11280 NULL((void*)0), child,
11281 "Invalid value for minOccurs (must be 0 or 1)",
11282 NULL((void*)0));
11283 /* Reset to 1. */
11284 part->minOccurs = 1;
11285 }
11286 if (part->maxOccurs > 1) {
11287 xmlSchemaPCustomErr(ctxt,
11288 XML_SCHEMAP_COS_ALL_LIMITED,
11289 NULL((void*)0), child,
11290 "Invalid value for maxOccurs (must be 0 or 1)",
11291 NULL((void*)0));
11292 /* Reset to 1. */
11293 part->maxOccurs = 1;
11294 }
11295 if (last == NULL((void*)0))
11296 item->children = (xmlSchemaTreeItemPtr) part;
11297 else
11298 last->next = (xmlSchemaTreeItemPtr) part;
11299 last = part;
11300 }
11301 child = child->next;
11302 }
11303 if (child != NULL((void*)0)) {
11304 xmlSchemaPContentErr(ctxt,
11305 XML_SCHEMAP_S4S_ELEM_NOT_ALLOWED,
11306 NULL((void*)0), node, child, NULL((void*)0),
11307 "(annotation?, (annotation?, element*)");
11308 }
11309 } else {
11310 /* choice + sequence */
11311 xmlSchemaTreeItemPtr part = NULL((void*)0), last = NULL((void*)0);
11312
11313 while ((IS_SCHEMA(child, "element")((child != ((void*)0)) && (child->ns != ((void*)0)
) && (xmlStrEqual(child->name, (const xmlChar *) "element"
)) && (xmlStrEqual(child->ns->href, xmlSchemaNs
)))
) ||
11314 (IS_SCHEMA(child, "group")((child != ((void*)0)) && (child->ns != ((void*)0)
) && (xmlStrEqual(child->name, (const xmlChar *) "group"
)) && (xmlStrEqual(child->ns->href, xmlSchemaNs
)))
) ||
11315 (IS_SCHEMA(child, "any")((child != ((void*)0)) && (child->ns != ((void*)0)
) && (xmlStrEqual(child->name, (const xmlChar *) "any"
)) && (xmlStrEqual(child->ns->href, xmlSchemaNs
)))
) ||
11316 (IS_SCHEMA(child, "choice")((child != ((void*)0)) && (child->ns != ((void*)0)
) && (xmlStrEqual(child->name, (const xmlChar *) "choice"
)) && (xmlStrEqual(child->ns->href, xmlSchemaNs
)))
) ||
11317 (IS_SCHEMA(child, "sequence")((child != ((void*)0)) && (child->ns != ((void*)0)
) && (xmlStrEqual(child->name, (const xmlChar *) "sequence"
)) && (xmlStrEqual(child->ns->href, xmlSchemaNs
)))
)) {
11318
11319 if (IS_SCHEMA(child, "element")((child != ((void*)0)) && (child->ns != ((void*)0)
) && (xmlStrEqual(child->name, (const xmlChar *) "element"
)) && (xmlStrEqual(child->ns->href, xmlSchemaNs
)))
) {
11320 part = (xmlSchemaTreeItemPtr)
11321 xmlSchemaParseElement(ctxt, schema, child, &isElemRef, 0);
11322 if (part && isElemRef)
11323 hasRefs++;
11324 } else if (IS_SCHEMA(child, "group")((child != ((void*)0)) && (child->ns != ((void*)0)
) && (xmlStrEqual(child->name, (const xmlChar *) "group"
)) && (xmlStrEqual(child->ns->href, xmlSchemaNs
)))
) {
11325 part =
11326 xmlSchemaParseModelGroupDefRef(ctxt, schema, child);
11327 if (part != NULL((void*)0))
11328 hasRefs++;
11329 /*
11330 * Handle redefinitions.
11331 */
11332 if (ctxt->isRedefine && ctxt->redef &&
11333 (ctxt->redef->item->type == XML_SCHEMA_TYPE_GROUP) &&
11334 part && part->children)
11335 {
11336 if ((xmlSchemaGetQNameRefName(part->children)((xmlSchemaQNameRefPtr) (part->children))->name ==
11337 ctxt->redef->refName) &&
11338 (xmlSchemaGetQNameRefTargetNs(part->children)((xmlSchemaQNameRefPtr) (part->children))->targetNamespace ==
11339 ctxt->redef->refTargetNs))
11340 {
11341 /*
11342 * SPEC src-redefine:
11343 * (6.1) "If it has a <group> among its contents at
11344 * some level the `actual value` of whose ref
11345 * [attribute] is the same as the `actual value` of
11346 * its own name attribute plus target namespace, then
11347 * all of the following must be true:"
11348 * (6.1.1) "It must have exactly one such group."
11349 */
11350 if (ctxt->redefCounter != 0) {
11351 xmlChar *str = NULL((void*)0);
11352
11353 xmlSchemaCustomErr(ACTXT_CAST(xmlSchemaAbstractCtxtPtr) ctxt,
11354 XML_SCHEMAP_SRC_REDEFINE, child, NULL((void*)0),
11355 "The redefining model group definition "
11356 "'%s' must not contain more than one "
11357 "reference to the redefined definition",
11358 xmlSchemaFormatQName(&str,
11359 ctxt->redef->refTargetNs,
11360 ctxt->redef->refName),
11361 NULL((void*)0));
11362 FREE_AND_NULL(str)if ((str) != ((void*)0)) { xmlFree((xmlChar *) (str)); str = (
(void*)0); }
11363 part = NULL((void*)0);
11364 } else if (((WXS_PARTICLE(part)(xmlSchemaParticlePtr) (part))->minOccurs != 1) ||
11365 ((WXS_PARTICLE(part)(xmlSchemaParticlePtr) (part))->maxOccurs != 1))
11366 {
11367 xmlChar *str = NULL((void*)0);
11368 /*
11369 * SPEC src-redefine:
11370 * (6.1.2) "The `actual value` of both that
11371 * group's minOccurs and maxOccurs [attribute]
11372 * must be 1 (or `absent`).
11373 */
11374 xmlSchemaCustomErr(ACTXT_CAST(xmlSchemaAbstractCtxtPtr) ctxt,
11375 XML_SCHEMAP_SRC_REDEFINE, child, NULL((void*)0),
11376 "The redefining model group definition "
11377 "'%s' must not contain a reference to the "
11378 "redefined definition with a "
11379 "maxOccurs/minOccurs other than 1",
11380 xmlSchemaFormatQName(&str,
11381 ctxt->redef->refTargetNs,
11382 ctxt->redef->refName),
11383 NULL((void*)0));
11384 FREE_AND_NULL(str)if ((str) != ((void*)0)) { xmlFree((xmlChar *) (str)); str = (
(void*)0); }
11385 part = NULL((void*)0);
11386 }
11387 ctxt->redef->reference = WXS_BASIC_CAST(xmlSchemaBasicItemPtr) part;
11388 ctxt->redefCounter++;
11389 }
11390 }
11391 } else if (IS_SCHEMA(child, "any")((child != ((void*)0)) && (child->ns != ((void*)0)
) && (xmlStrEqual(child->name, (const xmlChar *) "any"
)) && (xmlStrEqual(child->ns->href, xmlSchemaNs
)))
) {
11392 part = (xmlSchemaTreeItemPtr)
11393 xmlSchemaParseAny(ctxt, schema, child);
11394 } else if (IS_SCHEMA(child, "choice")((child != ((void*)0)) && (child->ns != ((void*)0)
) && (xmlStrEqual(child->name, (const xmlChar *) "choice"
)) && (xmlStrEqual(child->ns->href, xmlSchemaNs
)))
) {
11395 part = xmlSchemaParseModelGroup(ctxt, schema, child,
11396 XML_SCHEMA_TYPE_CHOICE, 1);
11397 } else if (IS_SCHEMA(child, "sequence")((child != ((void*)0)) && (child->ns != ((void*)0)
) && (xmlStrEqual(child->name, (const xmlChar *) "sequence"
)) && (xmlStrEqual(child->ns->href, xmlSchemaNs
)))
) {
11398 part = xmlSchemaParseModelGroup(ctxt, schema, child,
11399 XML_SCHEMA_TYPE_SEQUENCE, 1);
11400 }
11401 if (part != NULL((void*)0)) {
11402 if (last == NULL((void*)0))
11403 item->children = part;
11404 else
11405 last->next = part;
11406 last = part;
11407 }
11408 child = child->next;
11409 }
11410 if (child != NULL((void*)0)) {
11411 xmlSchemaPContentErr(ctxt,
11412 XML_SCHEMAP_S4S_ELEM_NOT_ALLOWED,
11413 NULL((void*)0), node, child, NULL((void*)0),
11414 "(annotation?, (element | group | choice | sequence | any)*)");
11415 }
11416 }
11417 if ((max == 0) && (min == 0))
11418 return (NULL((void*)0));
11419 if (hasRefs) {
11420 /*
11421 * We need to resolve references.
11422 */
11423 WXS_ADD_PENDING(ctxt, item)xmlSchemaAddItemSize(&((ctxt)->constructor->pending
), 10, item)
;
11424 }
11425 if (withParticle)
11426 return ((xmlSchemaTreeItemPtr) particle);
11427 else
11428 return ((xmlSchemaTreeItemPtr) item);
11429}
11430
11431/**
11432 * xmlSchemaParseRestriction:
11433 * @ctxt: a schema validation context
11434 * @schema: the schema being built
11435 * @node: a subtree containing XML Schema information
11436 *
11437 * parse a XML schema Restriction definition
11438 * *WARNING* this interface is highly subject to change
11439 *
11440 * Returns the type definition or NULL in case of error
11441 */
11442static xmlSchemaTypePtr
11443xmlSchemaParseRestriction(xmlSchemaParserCtxtPtr ctxt, xmlSchemaPtr schema,
11444 xmlNodePtr node, xmlSchemaTypeType parentType)
11445{
11446 xmlSchemaTypePtr type;
11447 xmlNodePtr child = NULL((void*)0);
11448 xmlAttrPtr attr;
11449
11450 if ((ctxt == NULL((void*)0)) || (schema == NULL((void*)0)) || (node == NULL((void*)0)))
11451 return (NULL((void*)0));
11452 /* Not a component, don't create it. */
11453 type = ctxt->ctxtType;
11454 type->flags |= XML_SCHEMAS_TYPE_DERIVATION_METHOD_RESTRICTION1 << 2;
11455
11456 /*
11457 * Check for illegal attributes.
11458 */
11459 attr = node->properties;
11460 while (attr != NULL((void*)0)) {
11461 if (attr->ns == NULL((void*)0)) {
11462 if ((!xmlStrEqual(attr->name, BAD_CAST(xmlChar *) "id")) &&
11463 (!xmlStrEqual(attr->name, BAD_CAST(xmlChar *) "base"))) {
11464 xmlSchemaPIllegalAttrErr(ctxt,
11465 XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL((void*)0), attr);
11466 }
11467 } else if (xmlStrEqual(attr->ns->href, xmlSchemaNs)) {
11468 xmlSchemaPIllegalAttrErr(ctxt,
11469 XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL((void*)0), attr);
11470 }
11471 attr = attr->next;
11472 }
11473 /*
11474 * Extract and validate attributes.
11475 */
11476 xmlSchemaPValAttrID(ctxt, node, BAD_CAST(xmlChar *) "id");
11477 /*
11478 * Attribute
11479 */
11480 /*
11481 * Extract the base type. The "base" attribute is mandatory if inside
11482 * a complex type or if redefining.
11483 *
11484 * SPEC (1.2) "...otherwise (<restriction> has no <simpleType> "
11485 * among its [children]), the simple type definition which is
11486 * the {content type} of the type definition `resolved` to by
11487 * the `actual value` of the base [attribute]"
11488 */
11489 if (xmlSchemaPValAttrQName(ctxt, schema, NULL((void*)0), node, "base",
11490 &(type->baseNs), &(type->base)) == 0)
11491 {
11492 if ((type->base == NULL((void*)0)) && (type->type == XML_SCHEMA_TYPE_COMPLEX)) {
11493 xmlSchemaPMissingAttrErr(ctxt,
11494 XML_SCHEMAP_S4S_ATTR_MISSING,
11495 NULL((void*)0), node, "base", NULL((void*)0));
11496 } else if ((ctxt->isRedefine) &&
11497 (type->flags & XML_SCHEMAS_TYPE_GLOBAL1 << 3))
11498 {
11499 if (type->base == NULL((void*)0)) {
11500 xmlSchemaPMissingAttrErr(ctxt,
11501 XML_SCHEMAP_S4S_ATTR_MISSING,
11502 NULL((void*)0), node, "base", NULL((void*)0));
11503 } else if ((! xmlStrEqual(type->base, type->name)) ||
11504 (! xmlStrEqual(type->baseNs, type->targetNamespace)))
11505 {
11506 xmlChar *str1 = NULL((void*)0), *str2 = NULL((void*)0);
11507 /*
11508 * REDEFINE: SPEC src-redefine (5)
11509 * "Within the [children], each <simpleType> must have a
11510 * <restriction> among its [children] ... the `actual value` of
11511 * whose base [attribute] must be the same as the `actual value`
11512 * of its own name attribute plus target namespace;"
11513 */
11514 xmlSchemaPCustomErrExt(ctxt, XML_SCHEMAP_SRC_REDEFINE,
11515 NULL((void*)0), node, "This is a redefinition, but the QName "
11516 "value '%s' of the 'base' attribute does not match the "
11517 "type's designation '%s'",
11518 xmlSchemaFormatQName(&str1, type->baseNs, type->base),
11519 xmlSchemaFormatQName(&str2, type->targetNamespace,
11520 type->name), NULL((void*)0));
11521 FREE_AND_NULL(str1)if ((str1) != ((void*)0)) { xmlFree((xmlChar *) (str1)); str1
= ((void*)0); }
;
11522 FREE_AND_NULL(str2)if ((str2) != ((void*)0)) { xmlFree((xmlChar *) (str2)); str2
= ((void*)0); }
;
11523 /* Avoid confusion and erase the values. */
11524 type->base = NULL((void*)0);
11525 type->baseNs = NULL((void*)0);
11526 }
11527 }
11528 }
11529 /*
11530 * And now for the children...
11531 */
11532 child = node->children;
11533 if (IS_SCHEMA(child, "annotation")((child != ((void*)0)) && (child->ns != ((void*)0)
) && (xmlStrEqual(child->name, (const xmlChar *) "annotation"
)) && (xmlStrEqual(child->ns->href, xmlSchemaNs
)))
) {
11534 /*
11535 * Add the annotation to the simple type ancestor.
11536 */
11537 xmlSchemaAddAnnotation((xmlSchemaAnnotItemPtr) type,
11538 xmlSchemaParseAnnotation(ctxt, child, 1));
11539 child = child->next;
11540 }
11541 if (parentType == XML_SCHEMA_TYPE_SIMPLE) {
11542 /*
11543 * Corresponds to <simpleType><restriction><simpleType>.
11544 */
11545 if (IS_SCHEMA(child, "simpleType")((child != ((void*)0)) && (child->ns != ((void*)0)
) && (xmlStrEqual(child->name, (const xmlChar *) "simpleType"
)) && (xmlStrEqual(child->ns->href, xmlSchemaNs
)))
) {
11546 if (type->base != NULL((void*)0)) {
11547 /*
11548 * src-restriction-base-or-simpleType
11549 * Either the base [attribute] or the simpleType [child] of the
11550 * <restriction> element must be present, but not both.
11551 */
11552 xmlSchemaPContentErr(ctxt,
11553 XML_SCHEMAP_SRC_RESTRICTION_BASE_OR_SIMPLETYPE,
11554 NULL((void*)0), node, child,
11555 "The attribute 'base' and the <simpleType> child are "
11556 "mutually exclusive", NULL((void*)0));
11557 } else {
11558 type->baseType = (xmlSchemaTypePtr)
11559 xmlSchemaParseSimpleType(ctxt, schema, child, 0);
11560 }
11561 child = child->next;
11562 } else if (type->base == NULL((void*)0)) {
11563 xmlSchemaPContentErr(ctxt,
11564 XML_SCHEMAP_SRC_RESTRICTION_BASE_OR_SIMPLETYPE,
11565 NULL((void*)0), node, child,
11566 "Either the attribute 'base' or a <simpleType> child "
11567 "must be present", NULL((void*)0));
11568 }
11569 } else if (parentType == XML_SCHEMA_TYPE_COMPLEX_CONTENT) {
11570 /*
11571 * Corresponds to <complexType><complexContent><restriction>...
11572 * followed by:
11573 *
11574 * Model groups <all>, <choice> and <sequence>.
11575 */
11576 if (IS_SCHEMA(child, "all")((child != ((void*)0)) && (child->ns != ((void*)0)
) && (xmlStrEqual(child->name, (const xmlChar *) "all"
)) && (xmlStrEqual(child->ns->href, xmlSchemaNs
)))
) {
11577 type->subtypes = (xmlSchemaTypePtr)
11578 xmlSchemaParseModelGroup(ctxt, schema, child,
11579 XML_SCHEMA_TYPE_ALL, 1);
11580 child = child->next;
11581 } else if (IS_SCHEMA(child, "choice")((child != ((void*)0)) && (child->ns != ((void*)0)
) && (xmlStrEqual(child->name, (const xmlChar *) "choice"
)) && (xmlStrEqual(child->ns->href, xmlSchemaNs
)))
) {
11582 type->subtypes = (xmlSchemaTypePtr)
11583 xmlSchemaParseModelGroup(ctxt,
11584 schema, child, XML_SCHEMA_TYPE_CHOICE, 1);
11585 child = child->next;
11586 } else if (IS_SCHEMA(child, "sequence")((child != ((void*)0)) && (child->ns != ((void*)0)
) && (xmlStrEqual(child->name, (const xmlChar *) "sequence"
)) && (xmlStrEqual(child->ns->href, xmlSchemaNs
)))
) {
11587 type->subtypes = (xmlSchemaTypePtr)
11588 xmlSchemaParseModelGroup(ctxt, schema, child,
11589 XML_SCHEMA_TYPE_SEQUENCE, 1);
11590 child = child->next;
11591 /*
11592 * Model group reference <group>.
11593 */
11594 } else if (IS_SCHEMA(child, "group")((child != ((void*)0)) && (child->ns != ((void*)0)
) && (xmlStrEqual(child->name, (const xmlChar *) "group"
)) && (xmlStrEqual(child->ns->href, xmlSchemaNs
)))
) {
11595 type->subtypes = (xmlSchemaTypePtr)
11596 xmlSchemaParseModelGroupDefRef(ctxt, schema, child);
11597 /*
11598 * Note that the reference will be resolved in
11599 * xmlSchemaResolveTypeReferences();
11600 */
11601 child = child->next;
11602 }
11603 } else if (parentType == XML_SCHEMA_TYPE_SIMPLE_CONTENT) {
11604 /*
11605 * Corresponds to <complexType><simpleContent><restriction>...
11606 *
11607 * "1.1 the simple type definition corresponding to the <simpleType>
11608 * among the [children] of <restriction> if there is one;"
11609 */
11610 if (IS_SCHEMA(child, "simpleType")((child != ((void*)0)) && (child->ns != ((void*)0)
) && (xmlStrEqual(child->name, (const xmlChar *) "simpleType"
)) && (xmlStrEqual(child->ns->href, xmlSchemaNs
)))
) {
11611 /*
11612 * We will store the to-be-restricted simple type in
11613 * type->contentTypeDef *temporarily*.
11614 */
11615 type->contentTypeDef = (xmlSchemaTypePtr)
11616 xmlSchemaParseSimpleType(ctxt, schema, child, 0);
11617 if ( type->contentTypeDef == NULL((void*)0))
11618 return (NULL((void*)0));
11619 child = child->next;
11620 }
11621 }
11622
11623 if ((parentType == XML_SCHEMA_TYPE_SIMPLE) ||
11624 (parentType == XML_SCHEMA_TYPE_SIMPLE_CONTENT)) {
11625 xmlSchemaFacetPtr facet, lastfacet = NULL((void*)0);
11626 /*
11627 * Corresponds to <complexType><simpleContent><restriction>...
11628 * <simpleType><restriction>...
11629 */
11630
11631 /*
11632 * Add the facets to the simple type ancestor.
11633 */
11634 /*
11635 * TODO: Datatypes: 4.1.3 Constraints on XML Representation of
11636 * Simple Type Definition Schema Representation Constraint:
11637 * *Single Facet Value*
11638 */
11639 while ((IS_SCHEMA(child, "minInclusive")((child != ((void*)0)) && (child->ns != ((void*)0)
) && (xmlStrEqual(child->name, (const xmlChar *) "minInclusive"
)) && (xmlStrEqual(child->ns->href, xmlSchemaNs
)))
) ||
11640 (IS_SCHEMA(child, "minExclusive")((child != ((void*)0)) && (child->ns != ((void*)0)
) && (xmlStrEqual(child->name, (const xmlChar *) "minExclusive"
)) && (xmlStrEqual(child->ns->href, xmlSchemaNs
)))
) ||
11641 (IS_SCHEMA(child, "maxInclusive")((child != ((void*)0)) && (child->ns != ((void*)0)
) && (xmlStrEqual(child->name, (const xmlChar *) "maxInclusive"
)) && (xmlStrEqual(child->ns->href, xmlSchemaNs
)))
) ||
11642 (IS_SCHEMA(child, "maxExclusive")((child != ((void*)0)) && (child->ns != ((void*)0)
) && (xmlStrEqual(child->name, (const xmlChar *) "maxExclusive"
)) && (xmlStrEqual(child->ns->href, xmlSchemaNs
)))
) ||
11643 (IS_SCHEMA(child, "totalDigits")((child != ((void*)0)) && (child->ns != ((void*)0)
) && (xmlStrEqual(child->name, (const xmlChar *) "totalDigits"
)) && (xmlStrEqual(child->ns->href, xmlSchemaNs
)))
) ||
11644 (IS_SCHEMA(child, "fractionDigits")((child != ((void*)0)) && (child->ns != ((void*)0)
) && (xmlStrEqual(child->name, (const xmlChar *) "fractionDigits"
)) && (xmlStrEqual(child->ns->href, xmlSchemaNs
)))
) ||
11645 (IS_SCHEMA(child, "pattern")((child != ((void*)0)) && (child->ns != ((void*)0)
) && (xmlStrEqual(child->name, (const xmlChar *) "pattern"
)) && (xmlStrEqual(child->ns->href, xmlSchemaNs
)))
) ||
11646 (IS_SCHEMA(child, "enumeration")((child != ((void*)0)) && (child->ns != ((void*)0)
) && (xmlStrEqual(child->name, (const xmlChar *) "enumeration"
)) && (xmlStrEqual(child->ns->href, xmlSchemaNs
)))
) ||
11647 (IS_SCHEMA(child, "whiteSpace")((child != ((void*)0)) && (child->ns != ((void*)0)
) && (xmlStrEqual(child->name, (const xmlChar *) "whiteSpace"
)) && (xmlStrEqual(child->ns->href, xmlSchemaNs
)))
) ||
11648 (IS_SCHEMA(child, "length")((child != ((void*)0)) && (child->ns != ((void*)0)
) && (xmlStrEqual(child->name, (const xmlChar *) "length"
)) && (xmlStrEqual(child->ns->href, xmlSchemaNs
)))
) ||
11649 (IS_SCHEMA(child, "maxLength")((child != ((void*)0)) && (child->ns != ((void*)0)
) && (xmlStrEqual(child->name, (const xmlChar *) "maxLength"
)) && (xmlStrEqual(child->ns->href, xmlSchemaNs
)))
) ||
11650 (IS_SCHEMA(child, "minLength")((child != ((void*)0)) && (child->ns != ((void*)0)
) && (xmlStrEqual(child->name, (const xmlChar *) "minLength"
)) && (xmlStrEqual(child->ns->href, xmlSchemaNs
)))
)) {
11651 facet = xmlSchemaParseFacet(ctxt, schema, child);
11652 if (facet != NULL((void*)0)) {
11653 if (lastfacet == NULL((void*)0))
11654 type->facets = facet;
11655 else
11656 lastfacet->next = facet;
11657 lastfacet = facet;
11658 lastfacet->next = NULL((void*)0);
11659 }
11660 child = child->next;
11661 }
11662 /*
11663 * Create links for derivation and validation.
11664 */
11665 if (type->facets != NULL((void*)0)) {
11666 xmlSchemaFacetLinkPtr facetLink, lastFacetLink = NULL((void*)0);
11667
11668 facet = type->facets;
11669 do {
11670 facetLink = (xmlSchemaFacetLinkPtr)
11671 xmlMalloc(sizeof(xmlSchemaFacetLink));
11672 if (facetLink == NULL((void*)0)) {
11673 xmlSchemaPErrMemory(ctxt, "allocating a facet link", NULL((void*)0));
11674 xmlFree(facetLink);
11675 return (NULL((void*)0));
11676 }
11677 facetLink->facet = facet;
11678 facetLink->next = NULL((void*)0);
11679 if (lastFacetLink == NULL((void*)0))
11680 type->facetSet = facetLink;
11681 else
11682 lastFacetLink->next = facetLink;
11683 lastFacetLink = facetLink;
11684 facet = facet->next;
11685 } while (facet != NULL((void*)0));
11686 }
11687 }
11688 if (type->type == XML_SCHEMA_TYPE_COMPLEX) {
11689 /*
11690 * Attribute uses/declarations.
11691 */
11692 if (xmlSchemaParseLocalAttributes(ctxt, schema, &child,
11693 (xmlSchemaItemListPtr *) &(type->attrUses),
11694 XML_SCHEMA_TYPE_RESTRICTION, NULL((void*)0)) == -1)
11695 return(NULL((void*)0));
11696 /*
11697 * Attribute wildcard.
11698 */
11699 if (IS_SCHEMA(child, "anyAttribute")((child != ((void*)0)) && (child->ns != ((void*)0)
) && (xmlStrEqual(child->name, (const xmlChar *) "anyAttribute"
)) && (xmlStrEqual(child->ns->href, xmlSchemaNs
)))
) {
11700 type->attributeWildcard =
11701 xmlSchemaParseAnyAttribute(ctxt, schema, child);
11702 child = child->next;
11703 }
11704 }
11705 if (child != NULL((void*)0)) {
11706 if (parentType == XML_SCHEMA_TYPE_COMPLEX_CONTENT) {
11707 xmlSchemaPContentErr(ctxt,
11708 XML_SCHEMAP_S4S_ELEM_NOT_ALLOWED,
11709 NULL((void*)0), node, child, NULL((void*)0),
11710 "annotation?, (group | all | choice | sequence)?, "
11711 "((attribute | attributeGroup)*, anyAttribute?))");
11712 } else if (parentType == XML_SCHEMA_TYPE_SIMPLE_CONTENT) {
11713 xmlSchemaPContentErr(ctxt,
11714 XML_SCHEMAP_S4S_ELEM_NOT_ALLOWED,
11715 NULL((void*)0), node, child, NULL((void*)0),
11716 "(annotation?, (simpleType?, (minExclusive | minInclusive | "
11717 "maxExclusive | maxInclusive | totalDigits | fractionDigits | "
11718 "length | minLength | maxLength | enumeration | whiteSpace | "
11719 "pattern)*)?, ((attribute | attributeGroup)*, anyAttribute?))");
11720 } else {
11721 /* Simple type */
11722 xmlSchemaPContentErr(ctxt,
11723 XML_SCHEMAP_S4S_ELEM_NOT_ALLOWED,
11724 NULL((void*)0), node, child, NULL((void*)0),
11725 "(annotation?, (simpleType?, (minExclusive | minInclusive | "
11726 "maxExclusive | maxInclusive | totalDigits | fractionDigits | "
11727 "length | minLength | maxLength | enumeration | whiteSpace | "
11728 "pattern)*))");
11729 }
11730 }
11731 return (NULL((void*)0));
11732}
11733
11734/**
11735 * xmlSchemaParseExtension:
11736 * @ctxt: a schema validation context
11737 * @schema: the schema being built
11738 * @node: a subtree containing XML Schema information
11739 *
11740 * Parses an <extension>, which is found inside a
11741 * <simpleContent> or <complexContent>.
11742 * *WARNING* this interface is highly subject to change.
11743 *
11744 * TODO: Returns the type definition or NULL in case of error
11745 */
11746static xmlSchemaTypePtr
11747xmlSchemaParseExtension(xmlSchemaParserCtxtPtr ctxt, xmlSchemaPtr schema,
11748 xmlNodePtr node, xmlSchemaTypeType parentType)
11749{
11750 xmlSchemaTypePtr type;
11751 xmlNodePtr child = NULL((void*)0);
11752 xmlAttrPtr attr;
11753
11754 if ((ctxt == NULL((void*)0)) || (schema == NULL((void*)0)) || (node == NULL((void*)0)))
11755 return (NULL((void*)0));
11756 /* Not a component, don't create it. */
11757 type = ctxt->ctxtType;
11758 type->flags |= XML_SCHEMAS_TYPE_DERIVATION_METHOD_EXTENSION1 << 1;
11759
11760 /*
11761 * Check for illegal attributes.
11762 */
11763 attr = node->properties;
11764 while (attr != NULL((void*)0)) {
11765 if (attr->ns == NULL((void*)0)) {
11766 if ((!xmlStrEqual(attr->name, BAD_CAST(xmlChar *) "id")) &&
11767 (!xmlStrEqual(attr->name, BAD_CAST(xmlChar *) "base"))) {
11768 xmlSchemaPIllegalAttrErr(ctxt,
11769 XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL((void*)0), attr);
11770 }
11771 } else if (xmlStrEqual(attr->ns->href, xmlSchemaNs)) {
11772 xmlSchemaPIllegalAttrErr(ctxt,
11773 XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL((void*)0), attr);
11774 }
11775 attr = attr->next;
11776 }
11777
11778 xmlSchemaPValAttrID(ctxt, node, BAD_CAST(xmlChar *) "id");
11779
11780 /*
11781 * Attribute "base" - mandatory.
11782 */
11783 if ((xmlSchemaPValAttrQName(ctxt, schema, NULL((void*)0), node,
11784 "base", &(type->baseNs), &(type->base)) == 0) &&
11785 (type->base == NULL((void*)0))) {
11786 xmlSchemaPMissingAttrErr(ctxt,
11787 XML_SCHEMAP_S4S_ATTR_MISSING,
11788 NULL((void*)0), node, "base", NULL((void*)0));
11789 }
11790 /*
11791 * And now for the children...
11792 */
11793 child = node->children;
11794 if (IS_SCHEMA(child, "annotation")((child != ((void*)0)) && (child->ns != ((void*)0)
) && (xmlStrEqual(child->name, (const xmlChar *) "annotation"
)) && (xmlStrEqual(child->ns->href, xmlSchemaNs
)))
) {
11795 /*
11796 * Add the annotation to the type ancestor.
11797 */
11798 xmlSchemaAddAnnotation((xmlSchemaAnnotItemPtr) type,
11799 xmlSchemaParseAnnotation(ctxt, child, 1));
11800 child = child->next;
11801 }
11802 if (parentType == XML_SCHEMA_TYPE_COMPLEX_CONTENT) {
11803 /*
11804 * Corresponds to <complexType><complexContent><extension>... and:
11805 *
11806 * Model groups <all>, <choice>, <sequence> and <group>.
11807 */
11808 if (IS_SCHEMA(child, "all")((child != ((void*)0)) && (child->ns != ((void*)0)
) && (xmlStrEqual(child->name, (const xmlChar *) "all"
)) && (xmlStrEqual(child->ns->href, xmlSchemaNs
)))
) {
11809 type->subtypes = (xmlSchemaTypePtr)
11810 xmlSchemaParseModelGroup(ctxt, schema,
11811 child, XML_SCHEMA_TYPE_ALL, 1);
11812 child = child->next;
11813 } else if (IS_SCHEMA(child, "choice")((child != ((void*)0)) && (child->ns != ((void*)0)
) && (xmlStrEqual(child->name, (const xmlChar *) "choice"
)) && (xmlStrEqual(child->ns->href, xmlSchemaNs
)))
) {
11814 type->subtypes = (xmlSchemaTypePtr)
11815 xmlSchemaParseModelGroup(ctxt, schema,
11816 child, XML_SCHEMA_TYPE_CHOICE, 1);
11817 child = child->next;
11818 } else if (IS_SCHEMA(child, "sequence")((child != ((void*)0)) && (child->ns != ((void*)0)
) && (xmlStrEqual(child->name, (const xmlChar *) "sequence"
)) && (xmlStrEqual(child->ns->href, xmlSchemaNs
)))
) {
11819 type->subtypes = (xmlSchemaTypePtr)
11820 xmlSchemaParseModelGroup(ctxt, schema,
11821 child, XML_SCHEMA_TYPE_SEQUENCE, 1);
11822 child = child->next;
11823 } else if (IS_SCHEMA(child, "group")((child != ((void*)0)) && (child->ns != ((void*)0)
) && (xmlStrEqual(child->name, (const xmlChar *) "group"
)) && (xmlStrEqual(child->ns->href, xmlSchemaNs
)))
) {
11824 type->subtypes = (xmlSchemaTypePtr)
11825 xmlSchemaParseModelGroupDefRef(ctxt, schema, child);
11826 /*
11827 * Note that the reference will be resolved in
11828 * xmlSchemaResolveTypeReferences();
11829 */
11830 child = child->next;
11831 }
11832 }
11833 if (child != NULL((void*)0)) {
11834 /*
11835 * Attribute uses/declarations.
11836 */
11837 if (xmlSchemaParseLocalAttributes(ctxt, schema, &child,
11838 (xmlSchemaItemListPtr *) &(type->attrUses),
11839 XML_SCHEMA_TYPE_EXTENSION, NULL((void*)0)) == -1)
11840 return(NULL((void*)0));
11841 /*
11842 * Attribute wildcard.
11843 */
11844 if (IS_SCHEMA(child, "anyAttribute")((child != ((void*)0)) && (child->ns != ((void*)0)
) && (xmlStrEqual(child->name, (const xmlChar *) "anyAttribute"
)) && (xmlStrEqual(child->ns->href, xmlSchemaNs
)))
) {
11845 ctxt->ctxtType->attributeWildcard =
11846 xmlSchemaParseAnyAttribute(ctxt, schema, child);
11847 child = child->next;
11848 }
11849 }
11850 if (child != NULL((void*)0)) {
11851 if (parentType == XML_SCHEMA_TYPE_COMPLEX_CONTENT) {
11852 /* Complex content extension. */
11853 xmlSchemaPContentErr(ctxt,
11854 XML_SCHEMAP_S4S_ELEM_NOT_ALLOWED,
11855 NULL((void*)0), node, child, NULL((void*)0),
11856 "(annotation?, ((group | all | choice | sequence)?, "
11857 "((attribute | attributeGroup)*, anyAttribute?)))");
11858 } else {
11859 /* Simple content extension. */
11860 xmlSchemaPContentErr(ctxt,
11861 XML_SCHEMAP_S4S_ELEM_NOT_ALLOWED,
11862 NULL((void*)0), node, child, NULL((void*)0),
11863 "(annotation?, ((attribute | attributeGroup)*, "
11864 "anyAttribute?))");
11865 }
11866 }
11867 return (NULL((void*)0));
11868}
11869
11870/**
11871 * xmlSchemaParseSimpleContent:
11872 * @ctxt: a schema validation context
11873 * @schema: the schema being built
11874 * @node: a subtree containing XML Schema information
11875 *
11876 * parse a XML schema SimpleContent definition
11877 * *WARNING* this interface is highly subject to change
11878 *
11879 * Returns the type definition or NULL in case of error
11880 */
11881static int
11882xmlSchemaParseSimpleContent(xmlSchemaParserCtxtPtr ctxt,
11883 xmlSchemaPtr schema, xmlNodePtr node,
11884 int *hasRestrictionOrExtension)
11885{
11886 xmlSchemaTypePtr type;
11887 xmlNodePtr child = NULL((void*)0);
11888 xmlAttrPtr attr;
11889
11890 if ((ctxt == NULL((void*)0)) || (schema == NULL((void*)0)) || (node == NULL((void*)0)) ||
11891 (hasRestrictionOrExtension == NULL((void*)0)))
11892 return (-1);
11893 *hasRestrictionOrExtension = 0;
11894 /* Not a component, don't create it. */
11895 type = ctxt->ctxtType;
11896 type->contentType = XML_SCHEMA_CONTENT_SIMPLE;
11897 /*
11898 * Check for illegal attributes.
11899 */
11900 attr = node->properties;
11901 while (attr != NULL((void*)0)) {
11902 if (attr->ns == NULL((void*)0)) {
11903 if ((!xmlStrEqual(attr->name, BAD_CAST(xmlChar *) "id"))) {
11904 xmlSchemaPIllegalAttrErr(ctxt,
11905 XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL((void*)0), attr);
11906 }
11907 } else if (xmlStrEqual(attr->ns->href, xmlSchemaNs)) {
11908 xmlSchemaPIllegalAttrErr(ctxt,
11909 XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL((void*)0), attr);
11910 }
11911 attr = attr->next;
11912 }
11913
11914 xmlSchemaPValAttrID(ctxt, node, BAD_CAST(xmlChar *) "id");
11915
11916 /*
11917 * And now for the children...
11918 */
11919 child = node->children;
11920 if (IS_SCHEMA(child, "annotation")((child != ((void*)0)) && (child->ns != ((void*)0)
) && (xmlStrEqual(child->name, (const xmlChar *) "annotation"
)) && (xmlStrEqual(child->ns->href, xmlSchemaNs
)))
) {
11921 /*
11922 * Add the annotation to the complex type ancestor.
11923 */
11924 xmlSchemaAddAnnotation((xmlSchemaAnnotItemPtr) type,
11925 xmlSchemaParseAnnotation(ctxt, child, 1));
11926 child = child->next;
11927 }
11928 if (child == NULL((void*)0)) {
11929 xmlSchemaPContentErr(ctxt,
11930 XML_SCHEMAP_S4S_ELEM_MISSING,
11931 NULL((void*)0), node, NULL((void*)0), NULL((void*)0),
11932 "(annotation?, (restriction | extension))");
11933 }
11934 if (child == NULL((void*)0)) {
11935 xmlSchemaPContentErr(ctxt,
11936 XML_SCHEMAP_S4S_ELEM_MISSING,
11937 NULL((void*)0), node, NULL((void*)0), NULL((void*)0),
11938 "(annotation?, (restriction | extension))");
11939 }
11940 if (IS_SCHEMA(child, "restriction")((child != ((void*)0)) && (child->ns != ((void*)0)
) && (xmlStrEqual(child->name, (const xmlChar *) "restriction"
)) && (xmlStrEqual(child->ns->href, xmlSchemaNs
)))
) {
11941 xmlSchemaParseRestriction(ctxt, schema, child,
11942 XML_SCHEMA_TYPE_SIMPLE_CONTENT);
11943 (*hasRestrictionOrExtension) = 1;
11944 child = child->next;
11945 } else if (IS_SCHEMA(child, "extension")((child != ((void*)0)) && (child->ns != ((void*)0)
) && (xmlStrEqual(child->name, (const xmlChar *) "extension"
)) && (xmlStrEqual(child->ns->href, xmlSchemaNs
)))
) {
11946 xmlSchemaParseExtension(ctxt, schema, child,
11947 XML_SCHEMA_TYPE_SIMPLE_CONTENT);
11948 (*hasRestrictionOrExtension) = 1;
11949 child = child->next;
11950 }
11951 if (child != NULL((void*)0)) {
11952 xmlSchemaPContentErr(ctxt,
11953 XML_SCHEMAP_S4S_ELEM_NOT_ALLOWED,
11954 NULL((void*)0), node, child, NULL((void*)0),
11955 "(annotation?, (restriction | extension))");
11956 }
11957 return (0);
11958}
11959
11960/**
11961 * xmlSchemaParseComplexContent:
11962 * @ctxt: a schema validation context
11963 * @schema: the schema being built
11964 * @node: a subtree containing XML Schema information
11965 *
11966 * parse a XML schema ComplexContent definition
11967 * *WARNING* this interface is highly subject to change
11968 *
11969 * Returns the type definition or NULL in case of error
11970 */
11971static int
11972xmlSchemaParseComplexContent(xmlSchemaParserCtxtPtr ctxt,
11973 xmlSchemaPtr schema, xmlNodePtr node,
11974 int *hasRestrictionOrExtension)
11975{
11976 xmlSchemaTypePtr type;
11977 xmlNodePtr child = NULL((void*)0);
11978 xmlAttrPtr attr;
11979
11980 if ((ctxt == NULL((void*)0)) || (schema == NULL((void*)0)) || (node == NULL((void*)0)) ||
11981 (hasRestrictionOrExtension == NULL((void*)0)))
11982 return (-1);
11983 *hasRestrictionOrExtension = 0;
11984 /* Not a component, don't create it. */
11985 type = ctxt->ctxtType;
11986 /*
11987 * Check for illegal attributes.
11988 */
11989 attr = node->properties;
11990 while (attr != NULL((void*)0)) {
11991 if (attr->ns == NULL((void*)0)) {
11992 if ((!xmlStrEqual(attr->name, BAD_CAST(xmlChar *) "id")) &&
11993 (!xmlStrEqual(attr->name, BAD_CAST(xmlChar *) "mixed")))
11994 {
11995 xmlSchemaPIllegalAttrErr(ctxt,
11996 XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL((void*)0), attr);
11997 }
11998 } else if (xmlStrEqual(attr->ns->href, xmlSchemaNs)) {
11999 xmlSchemaPIllegalAttrErr(ctxt,
12000 XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL((void*)0), attr);
12001 }
12002 attr = attr->next;
12003 }
12004
12005 xmlSchemaPValAttrID(ctxt, node, BAD_CAST(xmlChar *) "id");
12006
12007 /*
12008 * Set the 'mixed' on the complex type ancestor.
12009 */
12010 if (xmlGetBooleanProp(ctxt, node, "mixed", 0)) {
12011 if ((type->flags & XML_SCHEMAS_TYPE_MIXED1 << 0) == 0)
12012 type->flags |= XML_SCHEMAS_TYPE_MIXED1 << 0;
12013 }
12014 child = node->children;
12015 if (IS_SCHEMA(child, "annotation")((child != ((void*)0)) && (child->ns != ((void*)0)
) && (xmlStrEqual(child->name, (const xmlChar *) "annotation"
)) && (xmlStrEqual(child->ns->href, xmlSchemaNs
)))
) {
12016 /*
12017 * Add the annotation to the complex type ancestor.
12018 */
12019 xmlSchemaAddAnnotation((xmlSchemaAnnotItemPtr) type,
12020 xmlSchemaParseAnnotation(ctxt, child, 1));
12021 child = child->next;
12022 }
12023 if (child == NULL((void*)0)) {
12024 xmlSchemaPContentErr(ctxt,
12025 XML_SCHEMAP_S4S_ELEM_MISSING,
12026 NULL((void*)0), node, NULL((void*)0),
12027 NULL((void*)0), "(annotation?, (restriction | extension))");
12028 }
12029 if (child == NULL((void*)0)) {
12030 xmlSchemaPContentErr(ctxt,
12031 XML_SCHEMAP_S4S_ELEM_MISSING,
12032 NULL((void*)0), node, NULL((void*)0),
12033 NULL((void*)0), "(annotation?, (restriction | extension))");
12034 }
12035 if (IS_SCHEMA(child, "restriction")((child != ((void*)0)) && (child->ns != ((void*)0)
) && (xmlStrEqual(child->name, (const xmlChar *) "restriction"
)) && (xmlStrEqual(child->ns->href, xmlSchemaNs
)))
) {
12036 xmlSchemaParseRestriction(ctxt, schema, child,
12037 XML_SCHEMA_TYPE_COMPLEX_CONTENT);
12038 (*hasRestrictionOrExtension) = 1;
12039 child = child->next;
12040 } else if (IS_SCHEMA(child, "extension")((child != ((void*)0)) && (child->ns != ((void*)0)
) && (xmlStrEqual(child->name, (const xmlChar *) "extension"
)) && (xmlStrEqual(child->ns->href, xmlSchemaNs
)))
) {
12041 xmlSchemaParseExtension(ctxt, schema, child,
12042 XML_SCHEMA_TYPE_COMPLEX_CONTENT);
12043 (*hasRestrictionOrExtension) = 1;
12044 child = child->next;
12045 }
12046 if (child != NULL((void*)0)) {
12047 xmlSchemaPContentErr(ctxt,
12048 XML_SCHEMAP_S4S_ELEM_NOT_ALLOWED,
12049 NULL((void*)0), node, child,
12050 NULL((void*)0), "(annotation?, (restriction | extension))");
12051 }
12052 return (0);
12053}
12054
12055/**
12056 * xmlSchemaParseComplexType:
12057 * @ctxt: a schema validation context
12058 * @schema: the schema being built
12059 * @node: a subtree containing XML Schema information
12060 *
12061 * parse a XML schema Complex Type definition
12062 * *WARNING* this interface is highly subject to change
12063 *
12064 * Returns the type definition or NULL in case of error
12065 */
12066static xmlSchemaTypePtr
12067xmlSchemaParseComplexType(xmlSchemaParserCtxtPtr ctxt, xmlSchemaPtr schema,
12068 xmlNodePtr node, int topLevel)
12069{
12070 xmlSchemaTypePtr type, ctxtType;
12071 xmlNodePtr child = NULL((void*)0);
12072 const xmlChar *name = NULL((void*)0);
12073 xmlAttrPtr attr;
12074 const xmlChar *attrValue;
12075#ifdef ENABLE_NAMED_LOCALS
12076 char buf[40];
12077#endif
12078 int final = 0, block = 0, hasRestrictionOrExtension = 0;
12079
12080
12081 if ((ctxt == NULL((void*)0)) || (schema == NULL((void*)0)) || (node == NULL((void*)0)))
12082 return (NULL((void*)0));
12083
12084 ctxtType = ctxt->ctxtType;
12085
12086 if (topLevel) {
12087 attr = xmlSchemaGetPropNode(node, "name");
12088 if (attr == NULL((void*)0)) {
12089 xmlSchemaPMissingAttrErr(ctxt,
12090 XML_SCHEMAP_S4S_ATTR_MISSING, NULL((void*)0), node, "name", NULL((void*)0));
12091 return (NULL((void*)0));
12092 } else if (xmlSchemaPValAttrNode(ctxt, NULL((void*)0), attr,
12093 xmlSchemaGetBuiltInType(XML_SCHEMAS_NCNAME), &name) != 0) {
12094 return (NULL((void*)0));
12095 }
12096 }
12097
12098 if (topLevel == 0) {
12099 /*
12100 * Parse as local complex type definition.
12101 */
12102#ifdef ENABLE_NAMED_LOCALS
12103 snprintf(buf, 39, "#CT%d", ctxt->counter++ + 1);
12104 type = xmlSchemaAddType(ctxt, schema,
12105 XML_SCHEMA_TYPE_COMPLEX,
12106 xmlDictLookup(ctxt->dict, (const xmlChar *)buf, -1),
12107 ctxt->targetNamespace, node, 0);
12108#else
12109 type = xmlSchemaAddType(ctxt, schema,
12110 XML_SCHEMA_TYPE_COMPLEX,
12111 NULL((void*)0), ctxt->targetNamespace, node, 0);
12112#endif
12113 if (type == NULL((void*)0))
12114 return (NULL((void*)0));
12115 name = type->name;
12116 type->node = node;
12117 type->type = XML_SCHEMA_TYPE_COMPLEX;
12118 /*
12119 * TODO: We need the target namespace.
12120 */
12121 } else {
12122 /*
12123 * Parse as global complex type definition.
12124 */
12125 type = xmlSchemaAddType(ctxt, schema,
12126 XML_SCHEMA_TYPE_COMPLEX,
12127 name, ctxt->targetNamespace, node, 1);
12128 if (type == NULL((void*)0))
12129 return (NULL((void*)0));
12130 type->node = node;
12131 type->type = XML_SCHEMA_TYPE_COMPLEX;
12132 type->flags |= XML_SCHEMAS_TYPE_GLOBAL1 << 3;
12133 }
12134 type->targetNamespace = ctxt->targetNamespace;
12135 /*
12136 * Handle attributes.
12137 */
12138 attr = node->properties;
12139 while (attr != NULL((void*)0)) {
12140 if (attr->ns == NULL((void*)0)) {
12141 if (xmlStrEqual(attr->name, BAD_CAST(xmlChar *) "id")) {
12142 /*
12143 * Attribute "id".
12144 */
12145 xmlSchemaPValAttrID(ctxt, node, BAD_CAST(xmlChar *) "id");
12146 } else if (xmlStrEqual(attr->name, BAD_CAST(xmlChar *) "mixed")) {
12147 /*
12148 * Attribute "mixed".
12149 */
12150 if (xmlSchemaPGetBoolNodeValue(ctxt,
12151 NULL((void*)0), (xmlNodePtr) attr))
12152 type->flags |= XML_SCHEMAS_TYPE_MIXED1 << 0;
12153 } else if (topLevel) {
12154 /*
12155 * Attributes of global complex type definitions.
12156 */
12157 if (xmlStrEqual(attr->name, BAD_CAST(xmlChar *) "name")) {
12158 /* Pass. */
12159 } else if (xmlStrEqual(attr->name, BAD_CAST(xmlChar *) "abstract")) {
12160 /*
12161 * Attribute "abstract".
12162 */
12163 if (xmlSchemaPGetBoolNodeValue(ctxt,
12164 NULL((void*)0), (xmlNodePtr) attr))
12165 type->flags |= XML_SCHEMAS_TYPE_ABSTRACT1 << 20;
12166 } else if (xmlStrEqual(attr->name, BAD_CAST(xmlChar *) "final")) {
12167 /*
12168 * Attribute "final".
12169 */
12170 attrValue = xmlSchemaGetNodeContent(ctxt,
12171 (xmlNodePtr) attr);
12172 if (xmlSchemaPValAttrBlockFinal(attrValue,
12173 &(type->flags),
12174 -1,
12175 XML_SCHEMAS_TYPE_FINAL_EXTENSION1 << 9,
12176 XML_SCHEMAS_TYPE_FINAL_RESTRICTION1 << 10,
12177 -1, -1, -1) != 0)
12178 {
12179 xmlSchemaPSimpleTypeErr(ctxt,
12180 XML_SCHEMAP_S4S_ATTR_INVALID_VALUE,
12181 NULL((void*)0), (xmlNodePtr) attr, NULL((void*)0),
12182 "(#all | List of (extension | restriction))",
12183 attrValue, NULL((void*)0), NULL((void*)0), NULL((void*)0));
12184 } else
12185 final = 1;
12186 } else if (xmlStrEqual(attr->name, BAD_CAST(xmlChar *) "block")) {
12187 /*
12188 * Attribute "block".
12189 */
12190 attrValue = xmlSchemaGetNodeContent(ctxt,
12191 (xmlNodePtr) attr);
12192 if (xmlSchemaPValAttrBlockFinal(attrValue, &(type->flags),
12193 -1,
12194 XML_SCHEMAS_TYPE_BLOCK_EXTENSION1 << 18,
12195 XML_SCHEMAS_TYPE_BLOCK_RESTRICTION1 << 19,
12196 -1, -1, -1) != 0) {
12197 xmlSchemaPSimpleTypeErr(ctxt,
12198 XML_SCHEMAP_S4S_ATTR_INVALID_VALUE,
12199 NULL((void*)0), (xmlNodePtr) attr, NULL((void*)0),
12200 "(#all | List of (extension | restriction)) ",
12201 attrValue, NULL((void*)0), NULL((void*)0), NULL((void*)0));
12202 } else
12203 block = 1;
12204 } else {
12205 xmlSchemaPIllegalAttrErr(ctxt,
12206 XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL((void*)0), attr);
12207 }
12208 } else {
12209 xmlSchemaPIllegalAttrErr(ctxt,
12210 XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL((void*)0), attr);
12211 }
12212 } else if (xmlStrEqual(attr->ns->href, xmlSchemaNs)) {
12213 xmlSchemaPIllegalAttrErr(ctxt,
12214 XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL((void*)0), attr);
12215 }
12216 attr = attr->next;
12217 }
12218 if (! block) {
12219 /*
12220 * Apply default "block" values.
12221 */
12222 if (schema->flags & XML_SCHEMAS_BLOCK_DEFAULT_RESTRICTION1 << 7)
12223 type->flags |= XML_SCHEMAS_TYPE_BLOCK_RESTRICTION1 << 19;
12224 if (schema->flags & XML_SCHEMAS_BLOCK_DEFAULT_EXTENSION1 << 6)
12225 type->flags |= XML_SCHEMAS_TYPE_BLOCK_EXTENSION1 << 18;
12226 }
12227 if (! final) {
12228 /*
12229 * Apply default "block" values.
12230 */
12231 if (schema->flags & XML_SCHEMAS_FINAL_DEFAULT_RESTRICTION1 << 3)
12232 type->flags |= XML_SCHEMAS_TYPE_FINAL_RESTRICTION1 << 10;
12233 if (schema->flags & XML_SCHEMAS_FINAL_DEFAULT_EXTENSION1 << 2)
12234 type->flags |= XML_SCHEMAS_TYPE_FINAL_EXTENSION1 << 9;
12235 }
12236 /*
12237 * And now for the children...
12238 */
12239 child = node->children;
12240 if (IS_SCHEMA(child, "annotation")((child != ((void*)0)) && (child->ns != ((void*)0)
) && (xmlStrEqual(child->name, (const xmlChar *) "annotation"
)) && (xmlStrEqual(child->ns->href, xmlSchemaNs
)))
) {
12241 type->annot = xmlSchemaParseAnnotation(ctxt, child, 1);
12242 child = child->next;
12243 }
12244 ctxt->ctxtType = type;
12245 if (IS_SCHEMA(child, "simpleContent")((child != ((void*)0)) && (child->ns != ((void*)0)
) && (xmlStrEqual(child->name, (const xmlChar *) "simpleContent"
)) && (xmlStrEqual(child->ns->href, xmlSchemaNs
)))
) {
12246 /*
12247 * <complexType><simpleContent>...
12248 * 3.4.3 : 2.2
12249 * Specifying mixed='true' when the <simpleContent>
12250 * alternative is chosen has no effect
12251 */
12252 if (type->flags & XML_SCHEMAS_TYPE_MIXED1 << 0)
12253 type->flags ^= XML_SCHEMAS_TYPE_MIXED1 << 0;
12254 xmlSchemaParseSimpleContent(ctxt, schema, child,
12255 &hasRestrictionOrExtension);
12256 child = child->next;
12257 } else if (IS_SCHEMA(child, "complexContent")((child != ((void*)0)) && (child->ns != ((void*)0)
) && (xmlStrEqual(child->name, (const xmlChar *) "complexContent"
)) && (xmlStrEqual(child->ns->href, xmlSchemaNs
)))
) {
12258 /*
12259 * <complexType><complexContent>...
12260 */
12261 type->contentType = XML_SCHEMA_CONTENT_EMPTY;
12262 xmlSchemaParseComplexContent(ctxt, schema, child,
12263 &hasRestrictionOrExtension);
12264 child = child->next;
12265 } else {
12266 /*
12267 * E.g <complexType><sequence>... or <complexType><attribute>... etc.
12268 *
12269 * SPEC
12270 * "...the third alternative (neither <simpleContent> nor
12271 * <complexContent>) is chosen. This case is understood as shorthand
12272 * for complex content restricting the `ur-type definition`, and the
12273 * details of the mappings should be modified as necessary.
12274 */
12275 type->baseType = xmlSchemaGetBuiltInType(XML_SCHEMAS_ANYTYPE);
12276 type->flags |= XML_SCHEMAS_TYPE_DERIVATION_METHOD_RESTRICTION1 << 2;
12277 /*
12278 * Parse model groups.
12279 */
12280 if (IS_SCHEMA(child, "all")((child != ((void*)0)) && (child->ns != ((void*)0)
) && (xmlStrEqual(child->name, (const xmlChar *) "all"
)) && (xmlStrEqual(child->ns->href, xmlSchemaNs
)))
) {
12281 type->subtypes = (xmlSchemaTypePtr)
12282 xmlSchemaParseModelGroup(ctxt, schema, child,
12283 XML_SCHEMA_TYPE_ALL, 1);
12284 child = child->next;
12285 } else if (IS_SCHEMA(child, "choice")((child != ((void*)0)) && (child->ns != ((void*)0)
) && (xmlStrEqual(child->name, (const xmlChar *) "choice"
)) && (xmlStrEqual(child->ns->href, xmlSchemaNs
)))
) {
12286 type->subtypes = (xmlSchemaTypePtr)
12287 xmlSchemaParseModelGroup(ctxt, schema, child,
12288 XML_SCHEMA_TYPE_CHOICE, 1);
12289 child = child->next;
12290 } else if (IS_SCHEMA(child, "sequence")((child != ((void*)0)) && (child->ns != ((void*)0)
) && (xmlStrEqual(child->name, (const xmlChar *) "sequence"
)) && (xmlStrEqual(child->ns->href, xmlSchemaNs
)))
) {
12291 type->subtypes = (xmlSchemaTypePtr)
12292 xmlSchemaParseModelGroup(ctxt, schema, child,
12293 XML_SCHEMA_TYPE_SEQUENCE, 1);
12294 child = child->next;
12295 } else if (IS_SCHEMA(child, "group")((child != ((void*)0)) && (child->ns != ((void*)0)
) && (xmlStrEqual(child->name, (const xmlChar *) "group"
)) && (xmlStrEqual(child->ns->href, xmlSchemaNs
)))
) {
12296 type->subtypes = (xmlSchemaTypePtr)
12297 xmlSchemaParseModelGroupDefRef(ctxt, schema, child);
12298 /*
12299 * Note that the reference will be resolved in
12300 * xmlSchemaResolveTypeReferences();
12301 */
12302 child = child->next;
12303 }
12304 /*
12305 * Parse attribute decls/refs.
12306 */
12307 if (xmlSchemaParseLocalAttributes(ctxt, schema, &child,
12308 (xmlSchemaItemListPtr *) &(type->attrUses),
12309 XML_SCHEMA_TYPE_RESTRICTION, NULL((void*)0)) == -1)
12310 return(NULL((void*)0));
12311 /*
12312 * Parse attribute wildcard.
12313 */
12314 if (IS_SCHEMA(child, "anyAttribute")((child != ((void*)0)) && (child->ns != ((void*)0)
) && (xmlStrEqual(child->name, (const xmlChar *) "anyAttribute"
)) && (xmlStrEqual(child->ns->href, xmlSchemaNs
)))
) {
12315 type->attributeWildcard = xmlSchemaParseAnyAttribute(ctxt, schema, child);
12316 child = child->next;
12317 }
12318 }
12319 if (child != NULL((void*)0)) {
12320 xmlSchemaPContentErr(ctxt,
12321 XML_SCHEMAP_S4S_ELEM_NOT_ALLOWED,
12322 NULL((void*)0), node, child,
12323 NULL((void*)0), "(annotation?, (simpleContent | complexContent | "
12324 "((group | all | choice | sequence)?, ((attribute | "
12325 "attributeGroup)*, anyAttribute?))))");
12326 }
12327 /*
12328 * REDEFINE: SPEC src-redefine (5)
12329 */
12330 if (topLevel && ctxt->isRedefine && (! hasRestrictionOrExtension)) {
12331 xmlSchemaPCustomErr(ctxt, XML_SCHEMAP_SRC_REDEFINE,
12332 NULL((void*)0), node, "This is a redefinition, thus the "
12333 "<complexType> must have a <restriction> or <extension> "
12334 "grand-child", NULL((void*)0));
12335 }
12336 ctxt->ctxtType = ctxtType;
12337 return (type);
12338}
12339
12340/************************************************************************
12341 * *
12342 * Validating using Schemas *
12343 * *
12344 ************************************************************************/
12345
12346/************************************************************************
12347 * *
12348 * Reading/Writing Schemas *
12349 * *
12350 ************************************************************************/
12351
12352#if 0 /* Will be enabled if it is clear what options are needed. */
12353/**
12354 * xmlSchemaParserCtxtSetOptions:
12355 * @ctxt: a schema parser context
12356 * @options: a combination of xmlSchemaParserOption
12357 *
12358 * Sets the options to be used during the parse.
12359 *
12360 * Returns 0 in case of success, -1 in case of an
12361 * API error.
12362 */
12363static int
12364xmlSchemaParserCtxtSetOptions(xmlSchemaParserCtxtPtr ctxt,
12365 int options)
12366
12367{
12368 int i;
12369
12370 if (ctxt == NULL((void*)0))
12371 return (-1);
12372 /*
12373 * WARNING: Change the start value if adding to the
12374 * xmlSchemaParseOption.
12375 */
12376 for (i = 1; i < (int) sizeof(int) * 8; i++) {
12377 if (options & 1<<i) {
12378 return (-1);
12379 }
12380 }
12381 ctxt->options = options;
12382 return (0);
12383}
12384
12385/**
12386 * xmlSchemaValidCtxtGetOptions:
12387 * @ctxt: a schema parser context
12388 *
12389 * Returns the option combination of the parser context.
12390 */
12391static int
12392xmlSchemaParserCtxtGetOptions(xmlSchemaParserCtxtPtr ctxt)
12393
12394{
12395 if (ctxt == NULL((void*)0))
12396 return (-1);
12397 else
12398 return (ctxt->options);
12399}
12400#endif
12401
12402/**
12403 * xmlSchemaNewParserCtxt:
12404 * @URL: the location of the schema
12405 *
12406 * Create an XML Schemas parse context for that file/resource expected
12407 * to contain an XML Schemas file.
12408 *
12409 * Returns the parser context or NULL in case of error
12410 */
12411xmlSchemaParserCtxtPtr
12412xmlSchemaNewParserCtxt(const char *URL)
12413{
12414 xmlSchemaParserCtxtPtr ret;
12415
12416 if (URL == NULL((void*)0))
12417 return (NULL((void*)0));
12418
12419 ret = xmlSchemaParserCtxtCreate();
12420 if (ret == NULL((void*)0))
12421 return(NULL((void*)0));
12422 ret->dict = xmlDictCreate();
12423 ret->URL = xmlDictLookup(ret->dict, (const xmlChar *) URL, -1);
12424 return (ret);
12425}
12426
12427/**
12428 * xmlSchemaNewMemParserCtxt:
12429 * @buffer: a pointer to a char array containing the schemas
12430 * @size: the size of the array
12431 *
12432 * Create an XML Schemas parse context for that memory buffer expected
12433 * to contain an XML Schemas file.
12434 *
12435 * Returns the parser context or NULL in case of error
12436 */
12437xmlSchemaParserCtxtPtr
12438xmlSchemaNewMemParserCtxt(const char *buffer, int size)
12439{
12440 xmlSchemaParserCtxtPtr ret;
12441
12442 if ((buffer == NULL((void*)0)) || (size <= 0))
12443 return (NULL((void*)0));
12444 ret = xmlSchemaParserCtxtCreate();
12445 if (ret == NULL((void*)0))
12446 return(NULL((void*)0));
12447 ret->buffer = buffer;
12448 ret->size = size;
12449 ret->dict = xmlDictCreate();
12450 return (ret);
12451}
12452
12453/**
12454 * xmlSchemaNewDocParserCtxt:
12455 * @doc: a preparsed document tree
12456 *
12457 * Create an XML Schemas parse context for that document.
12458 * NB. The document may be modified during the parsing process.
12459 *
12460 * Returns the parser context or NULL in case of error
12461 */
12462xmlSchemaParserCtxtPtr
12463xmlSchemaNewDocParserCtxt(xmlDocPtr doc)
12464{
12465 xmlSchemaParserCtxtPtr ret;
12466
12467 if (doc == NULL((void*)0))
12468 return (NULL((void*)0));
12469 ret = xmlSchemaParserCtxtCreate();
12470 if (ret == NULL((void*)0))
12471 return(NULL((void*)0));
12472 ret->doc = doc;
12473 ret->dict = xmlDictCreate();
12474 /* The application has responsibility for the document */
12475 ret->preserve = 1;
12476
12477 return (ret);
12478}
12479
12480/**
12481 * xmlSchemaFreeParserCtxt:
12482 * @ctxt: the schema parser context
12483 *
12484 * Free the resources associated to the schema parser context
12485 */
12486void
12487xmlSchemaFreeParserCtxt(xmlSchemaParserCtxtPtr ctxt)
12488{
12489 if (ctxt == NULL((void*)0))
12490 return;
12491 if (ctxt->doc != NULL((void*)0) && !ctxt->preserve)
12492 xmlFreeDoc(ctxt->doc);
12493 if (ctxt->vctxt != NULL((void*)0)) {
12494 xmlSchemaFreeValidCtxt(ctxt->vctxt);
12495 }
12496 if (ctxt->ownsConstructor && (ctxt->constructor != NULL((void*)0))) {
12497 xmlSchemaConstructionCtxtFree(ctxt->constructor);
12498 ctxt->constructor = NULL((void*)0);
12499 ctxt->ownsConstructor = 0;
12500 }
12501 if (ctxt->attrProhibs != NULL((void*)0))
12502 xmlSchemaItemListFree(ctxt->attrProhibs);
12503 xmlDictFree(ctxt->dict);
12504 xmlFree(ctxt);
12505}
12506
12507/************************************************************************
12508 * *
12509 * Building the content models *
12510 * *
12511 ************************************************************************/
12512
12513/**
12514 * xmlSchemaBuildContentModelForSubstGroup:
12515 *
12516 * Returns 1 if nillable, 0 otherwise
12517 */
12518static int
12519xmlSchemaBuildContentModelForSubstGroup(xmlSchemaParserCtxtPtr pctxt,
12520 xmlSchemaParticlePtr particle, int counter, xmlAutomataStatePtr end)
12521{
12522 xmlAutomataStatePtr start, tmp;
12523 xmlSchemaElementPtr elemDecl, member;
12524 xmlSchemaSubstGroupPtr substGroup;
12525 int i;
12526 int ret = 0;
12527
12528 elemDecl = (xmlSchemaElementPtr) particle->children;
12529 /*
12530 * Wrap the substitution group with a CHOICE.
12531 */
12532 start = pctxt->state;
12533 if (end == NULL((void*)0))
12534 end = xmlAutomataNewState(pctxt->am);
12535 substGroup = xmlSchemaSubstGroupGet(pctxt, elemDecl);
12536 if (substGroup == NULL((void*)0)) {
12537 xmlSchemaPErr(pctxt, WXS_ITEM_NODE(particle)xmlSchemaGetComponentNode((xmlSchemaBasicItemPtr) (particle)),
12538 XML_SCHEMAP_INTERNAL,
12539 "Internal error: xmlSchemaBuildContentModelForSubstGroup, "
12540 "declaration is marked having a subst. group but none "
12541 "available.\n", elemDecl->name, NULL((void*)0));
12542 return(0);
12543 }
12544 if (counter >= 0) {
12545 /*
12546 * NOTE that we put the declaration in, even if it's abstract.
12547 * However, an error will be raised during *validation* if an element
12548 * information item shall be validated against an abstract element
12549 * declaration.
12550 */
12551 tmp = xmlAutomataNewCountedTrans(pctxt->am, start, NULL((void*)0), counter);
12552 xmlAutomataNewTransition2(pctxt->am, tmp, end,
12553 elemDecl->name, elemDecl->targetNamespace, elemDecl);
12554 /*
12555 * Add subst. group members.
12556 */
12557 for (i = 0; i < substGroup->members->nbItems; i++) {
12558 member = (xmlSchemaElementPtr) substGroup->members->items[i];
12559 xmlAutomataNewTransition2(pctxt->am, tmp, end,
12560 member->name, member->targetNamespace, member);
12561 }
12562 } else if (particle->maxOccurs == 1) {
12563 /*
12564 * NOTE that we put the declaration in, even if it's abstract,
12565 */
12566 xmlAutomataNewEpsilon(pctxt->am,
12567 xmlAutomataNewTransition2(pctxt->am,
12568 start, NULL((void*)0),
12569 elemDecl->name, elemDecl->targetNamespace, elemDecl), end);
12570 /*
12571 * Add subst. group members.
12572 */
12573 for (i = 0; i < substGroup->members->nbItems; i++) {
12574 member = (xmlSchemaElementPtr) substGroup->members->items[i];
12575 /*
12576 * NOTE: This fixes bug #341150. xmlAutomataNewOnceTrans2()
12577 * was incorrectly used instead of xmlAutomataNewTransition2()
12578 * (seems like a copy&paste bug from the XML_SCHEMA_TYPE_ALL
12579 * section in xmlSchemaBuildAContentModel() ).
12580 * TODO: Check if xmlAutomataNewOnceTrans2() was instead
12581 * intended for the above "counter" section originally. I.e.,
12582 * check xs:all with subst-groups.
12583 *
12584 * tmp = xmlAutomataNewOnceTrans2(pctxt->am, start, NULL,
12585 * member->name, member->targetNamespace,
12586 * 1, 1, member);
12587 */
12588 tmp = xmlAutomataNewTransition2(pctxt->am, start, NULL((void*)0),
12589 member->name, member->targetNamespace, member);
12590 xmlAutomataNewEpsilon(pctxt->am, tmp, end);
12591 }
12592 } else {
12593 xmlAutomataStatePtr hop;
12594 int maxOccurs = particle->maxOccurs == UNBOUNDED(1 << 30) ?
12595 UNBOUNDED(1 << 30) : particle->maxOccurs - 1;
12596 int minOccurs = particle->minOccurs < 1 ? 0 : particle->minOccurs - 1;
12597
12598 counter =
12599 xmlAutomataNewCounter(pctxt->am, minOccurs,
12600 maxOccurs);
12601 hop = xmlAutomataNewState(pctxt->am);
12602
12603 xmlAutomataNewEpsilon(pctxt->am,
12604 xmlAutomataNewTransition2(pctxt->am,
12605 start, NULL((void*)0),
12606 elemDecl->name, elemDecl->targetNamespace, elemDecl),
12607 hop);
12608 /*
12609 * Add subst. group members.
12610 */
12611 for (i = 0; i < substGroup->members->nbItems; i++) {
12612 member = (xmlSchemaElementPtr) substGroup->members->items[i];
12613 xmlAutomataNewEpsilon(pctxt->am,
12614 xmlAutomataNewTransition2(pctxt->am,
12615 start, NULL((void*)0),
12616 member->name, member->targetNamespace, member),
12617 hop);
12618 }
12619 xmlAutomataNewCountedTrans(pctxt->am, hop, start, counter);
12620 xmlAutomataNewCounterTrans(pctxt->am, hop, end, counter);
12621 }
12622 if (particle->minOccurs == 0) {
12623 xmlAutomataNewEpsilon(pctxt->am, start, end);
12624 ret = 1;
12625 }
12626 pctxt->state = end;
12627 return(ret);
12628}
12629
12630/**
12631 * xmlSchemaBuildContentModelForElement:
12632 *
12633 * Returns 1 if nillable, 0 otherwise
12634 */
12635static int
12636xmlSchemaBuildContentModelForElement(xmlSchemaParserCtxtPtr ctxt,
12637 xmlSchemaParticlePtr particle)
12638{
12639 int ret = 0;
12640
12641 if (((xmlSchemaElementPtr) particle->children)->flags &
12642 XML_SCHEMAS_ELEM_SUBST_GROUP_HEAD1 << 17) {
12643 /*
12644 * Substitution groups.
12645 */
12646 ret = xmlSchemaBuildContentModelForSubstGroup(ctxt, particle, -1, NULL((void*)0));
12647 } else {
12648 xmlSchemaElementPtr elemDecl;
12649 xmlAutomataStatePtr start;
12650
12651 elemDecl = (xmlSchemaElementPtr) particle->children;
12652
12653 if (elemDecl->flags & XML_SCHEMAS_ELEM_ABSTRACT1 << 4)
12654 return(0);
12655 if (particle->maxOccurs == 1) {
12656 start = ctxt->state;
12657 ctxt->state = xmlAutomataNewTransition2(ctxt->am, start, NULL((void*)0),
12658 elemDecl->name, elemDecl->targetNamespace, elemDecl);
12659 } else if ((particle->maxOccurs >= UNBOUNDED(1 << 30)) &&
12660 (particle->minOccurs < 2)) {
12661 /* Special case. */
12662 start = ctxt->state;
12663 ctxt->state = xmlAutomataNewTransition2(ctxt->am, start, NULL((void*)0),
12664 elemDecl->name, elemDecl->targetNamespace, elemDecl);
12665 ctxt->state = xmlAutomataNewTransition2(ctxt->am, ctxt->state, ctxt->state,
12666 elemDecl->name, elemDecl->targetNamespace, elemDecl);
12667 } else {
12668 int counter;
12669 int maxOccurs = particle->maxOccurs == UNBOUNDED(1 << 30) ?
12670 UNBOUNDED(1 << 30) : particle->maxOccurs - 1;
12671 int minOccurs = particle->minOccurs < 1 ?
12672 0 : particle->minOccurs - 1;
12673
12674 start = xmlAutomataNewEpsilon(ctxt->am, ctxt->state, NULL((void*)0));
12675 counter = xmlAutomataNewCounter(ctxt->am, minOccurs, maxOccurs);
12676 ctxt->state = xmlAutomataNewTransition2(ctxt->am, start, NULL((void*)0),
12677 elemDecl->name, elemDecl->targetNamespace, elemDecl);
12678 xmlAutomataNewCountedTrans(ctxt->am, ctxt->state, start, counter);
12679 ctxt->state = xmlAutomataNewCounterTrans(ctxt->am, ctxt->state,
12680 NULL((void*)0), counter);
12681 }
12682 if (particle->minOccurs == 0) {
12683 xmlAutomataNewEpsilon(ctxt->am, start, ctxt->state);
12684 ret = 1;
12685 }
12686 }
12687 return(ret);
12688}
12689
12690/**
12691 * xmlSchemaBuildAContentModel:
12692 * @ctxt: the schema parser context
12693 * @particle: the particle component
12694 * @name: the complex type's name whose content is being built
12695 *
12696 * Create the automaton for the {content type} of a complex type.
12697 *
12698 * Returns 1 if the content is nillable, 0 otherwise
12699 */
12700static int
12701xmlSchemaBuildAContentModel(xmlSchemaParserCtxtPtr pctxt,
12702 xmlSchemaParticlePtr particle)
12703{
12704 int ret = 0, tmp2;
12705
12706 if (particle == NULL((void*)0)) {
12707 PERROR_INT("xmlSchemaBuildAContentModel", "particle is NULL")xmlSchemaInternalErr((xmlSchemaAbstractCtxtPtr) pctxt, "xmlSchemaBuildAContentModel"
, "particle is NULL");
;
12708 return(1);
12709 }
12710 if (particle->children == NULL((void*)0)) {
12711 /*
12712 * Just return in this case. A missing "term" of the particle
12713 * might arise due to an invalid "term" component.
12714 */
12715 return(1);
12716 }
12717
12718 switch (particle->children->type) {
12719 case XML_SCHEMA_TYPE_ANY: {
12720 xmlAutomataStatePtr start, end;
12721 xmlSchemaWildcardPtr wild;
12722 xmlSchemaWildcardNsPtr ns;
12723
12724 wild = (xmlSchemaWildcardPtr) particle->children;
12725
12726 start = pctxt->state;
12727 end = xmlAutomataNewState(pctxt->am);
12728
12729 if (particle->maxOccurs == 1) {
12730 if (wild->any == 1) {
12731 /*
12732 * We need to add both transitions:
12733 *
12734 * 1. the {"*", "*"} for elements in a namespace.
12735 */
12736 pctxt->state =
12737 xmlAutomataNewTransition2(pctxt->am,
12738 start, NULL((void*)0), BAD_CAST(xmlChar *) "*", BAD_CAST(xmlChar *) "*", wild);
12739 xmlAutomataNewEpsilon(pctxt->am, pctxt->state, end);
12740 /*
12741 * 2. the {"*"} for elements in no namespace.
12742 */
12743 pctxt->state =
12744 xmlAutomataNewTransition2(pctxt->am,
12745 start, NULL((void*)0), BAD_CAST(xmlChar *) "*", NULL((void*)0), wild);
12746 xmlAutomataNewEpsilon(pctxt->am, pctxt->state, end);
12747
12748 } else if (wild->nsSet != NULL((void*)0)) {
12749 ns = wild->nsSet;
12750 do {
12751 pctxt->state = start;
12752 pctxt->state = xmlAutomataNewTransition2(pctxt->am,
12753 pctxt->state, NULL((void*)0), BAD_CAST(xmlChar *) "*", ns->value, wild);
12754 xmlAutomataNewEpsilon(pctxt->am, pctxt->state, end);
12755 ns = ns->next;
12756 } while (ns != NULL((void*)0));
12757
12758 } else if (wild->negNsSet != NULL((void*)0)) {
12759 pctxt->state = xmlAutomataNewNegTrans(pctxt->am,
12760 start, end, BAD_CAST(xmlChar *) "*", wild->negNsSet->value,
12761 wild);
12762 }
12763 } else {
12764 int counter;
12765 xmlAutomataStatePtr hop;
12766 int maxOccurs =
12767 particle->maxOccurs == UNBOUNDED(1 << 30) ? UNBOUNDED(1 << 30) :
12768 particle->maxOccurs - 1;
12769 int minOccurs =
12770 particle->minOccurs < 1 ? 0 : particle->minOccurs - 1;
12771
12772 counter = xmlAutomataNewCounter(pctxt->am, minOccurs, maxOccurs);
12773 hop = xmlAutomataNewState(pctxt->am);
12774 if (wild->any == 1) {
12775 pctxt->state =
12776 xmlAutomataNewTransition2(pctxt->am,
12777 start, NULL((void*)0), BAD_CAST(xmlChar *) "*", BAD_CAST(xmlChar *) "*", wild);
12778 xmlAutomataNewEpsilon(pctxt->am, pctxt->state, hop);
12779 pctxt->state =
12780 xmlAutomataNewTransition2(pctxt->am,
12781 start, NULL((void*)0), BAD_CAST(xmlChar *) "*", NULL((void*)0), wild);
12782 xmlAutomataNewEpsilon(pctxt->am, pctxt->state, hop);
12783 } else if (wild->nsSet != NULL((void*)0)) {
12784 ns = wild->nsSet;
12785 do {
12786 pctxt->state =
12787 xmlAutomataNewTransition2(pctxt->am,
12788 start, NULL((void*)0), BAD_CAST(xmlChar *) "*", ns->value, wild);
12789 xmlAutomataNewEpsilon(pctxt->am, pctxt->state, hop);
12790 ns = ns->next;
12791 } while (ns != NULL((void*)0));
12792
12793 } else if (wild->negNsSet != NULL((void*)0)) {
12794 pctxt->state = xmlAutomataNewNegTrans(pctxt->am,
12795 start, hop, BAD_CAST(xmlChar *) "*", wild->negNsSet->value,
12796 wild);
12797 }
12798 xmlAutomataNewCountedTrans(pctxt->am, hop, start, counter);
12799 xmlAutomataNewCounterTrans(pctxt->am, hop, end, counter);
12800 }
12801 if (particle->minOccurs == 0) {
12802 xmlAutomataNewEpsilon(pctxt->am, start, end);
12803 ret = 1;
12804 }
12805 pctxt->state = end;
12806 break;
12807 }
12808 case XML_SCHEMA_TYPE_ELEMENT:
12809 ret = xmlSchemaBuildContentModelForElement(pctxt, particle);
12810 break;
12811 case XML_SCHEMA_TYPE_SEQUENCE:{
12812 xmlSchemaTreeItemPtr sub;
12813
12814 ret = 1;
12815 /*
12816 * If max and min occurrences are default (1) then
12817 * simply iterate over the particles of the <sequence>.
12818 */
12819 if ((particle->minOccurs == 1) && (particle->maxOccurs == 1)) {
12820 sub = particle->children->children;
12821
12822 while (sub != NULL((void*)0)) {
12823 tmp2 = xmlSchemaBuildAContentModel(pctxt,
12824 (xmlSchemaParticlePtr) sub);
12825 if (tmp2 != 1) ret = 0;
12826 sub = sub->next;
12827 }
12828 } else {
12829 xmlAutomataStatePtr oldstate = pctxt->state;
12830
12831 if (particle->maxOccurs >= UNBOUNDED(1 << 30)) {
12832 if (particle->minOccurs > 1) {
12833 xmlAutomataStatePtr tmp;
12834 int counter;
12835
12836 pctxt->state = xmlAutomataNewEpsilon(pctxt->am,
12837 oldstate, NULL((void*)0));
12838 oldstate = pctxt->state;
12839
12840 counter = xmlAutomataNewCounter(pctxt->am,
12841 particle->minOccurs - 1, UNBOUNDED(1 << 30));
12842
12843 sub = particle->children->children;
12844 while (sub != NULL((void*)0)) {
12845 tmp2 = xmlSchemaBuildAContentModel(pctxt,
12846 (xmlSchemaParticlePtr) sub);
12847 if (tmp2 != 1) ret = 0;
12848 sub = sub->next;
12849 }
12850 tmp = pctxt->state;
12851 xmlAutomataNewCountedTrans(pctxt->am, tmp,
12852 oldstate, counter);
12853 pctxt->state =
12854 xmlAutomataNewCounterTrans(pctxt->am, tmp,
12855 NULL((void*)0), counter);
12856 if (ret == 1)
12857 xmlAutomataNewEpsilon(pctxt->am,
12858 oldstate, pctxt->state);
12859
12860 } else {
12861 pctxt->state = xmlAutomataNewEpsilon(pctxt->am,
12862 oldstate, NULL((void*)0));
12863 oldstate = pctxt->state;
12864
12865 sub = particle->children->children;
12866 while (sub != NULL((void*)0)) {
12867 tmp2 = xmlSchemaBuildAContentModel(pctxt,
12868 (xmlSchemaParticlePtr) sub);
12869 if (tmp2 != 1) ret = 0;
12870 sub = sub->next;
12871 }
12872 xmlAutomataNewEpsilon(pctxt->am, pctxt->state,
12873 oldstate);
12874 /*
12875 * epsilon needed to block previous trans from
12876 * being allowed to enter back from another
12877 * construct
12878 */
12879 pctxt->state = xmlAutomataNewEpsilon(pctxt->am,
12880 pctxt->state, NULL((void*)0));
12881 if (particle->minOccurs == 0) {
12882 xmlAutomataNewEpsilon(pctxt->am,
12883 oldstate, pctxt->state);
12884 ret = 1;
12885 }
12886 }
12887 } else if ((particle->maxOccurs > 1)
12888 || (particle->minOccurs > 1)) {
12889 xmlAutomataStatePtr tmp;
12890 int counter;
12891
12892 pctxt->state = xmlAutomataNewEpsilon(pctxt->am,
12893 oldstate, NULL((void*)0));
12894 oldstate = pctxt->state;
12895
12896 counter = xmlAutomataNewCounter(pctxt->am,
12897 particle->minOccurs - 1,
12898 particle->maxOccurs - 1);
12899
12900 sub = particle->children->children;
12901 while (sub != NULL((void*)0)) {
12902 tmp2 = xmlSchemaBuildAContentModel(pctxt,
12903 (xmlSchemaParticlePtr) sub);
12904 if (tmp2 != 1) ret = 0;
12905 sub = sub->next;
12906 }
12907 tmp = pctxt->state;
12908 xmlAutomataNewCountedTrans(pctxt->am,
12909 tmp, oldstate, counter);
12910 pctxt->state =
12911 xmlAutomataNewCounterTrans(pctxt->am, tmp, NULL((void*)0),
12912 counter);
12913 if ((particle->minOccurs == 0) || (ret == 1)) {
12914 xmlAutomataNewEpsilon(pctxt->am,
12915 oldstate, pctxt->state);
12916 ret = 1;
12917 }
12918 } else {
12919 sub = particle->children->children;
12920 while (sub != NULL((void*)0)) {
12921 tmp2 = xmlSchemaBuildAContentModel(pctxt,
12922 (xmlSchemaParticlePtr) sub);
12923 if (tmp2 != 1) ret = 0;
12924 sub = sub->next;
12925 }
12926
12927 /*
12928 * epsilon needed to block previous trans from
12929 * being allowed to enter back from another
12930 * construct
12931 */
12932 pctxt->state = xmlAutomataNewEpsilon(pctxt->am,
12933 pctxt->state, NULL((void*)0));
12934
12935 if (particle->minOccurs == 0) {
12936 xmlAutomataNewEpsilon(pctxt->am, oldstate,
12937 pctxt->state);
12938 ret = 1;
12939 }
12940 }
12941 }
12942 break;
12943 }
12944 case XML_SCHEMA_TYPE_CHOICE:{
12945 xmlSchemaTreeItemPtr sub;
12946 xmlAutomataStatePtr start, end;
12947
12948 ret = 0;
12949 start = pctxt->state;
12950 end = xmlAutomataNewState(pctxt->am);
12951
12952 /*
12953 * iterate over the subtypes and remerge the end with an
12954 * epsilon transition
12955 */
12956 if (particle->maxOccurs == 1) {
12957 sub = particle->children->children;
12958 while (sub != NULL((void*)0)) {
12959 pctxt->state = start;
12960 tmp2 = xmlSchemaBuildAContentModel(pctxt,
12961 (xmlSchemaParticlePtr) sub);
12962 if (tmp2 == 1) ret = 1;
12963 xmlAutomataNewEpsilon(pctxt->am, pctxt->state, end);
12964 sub = sub->next;
12965 }
12966 } else {
12967 int counter;
12968 xmlAutomataStatePtr hop, base;
12969 int maxOccurs = particle->maxOccurs == UNBOUNDED(1 << 30) ?
12970 UNBOUNDED(1 << 30) : particle->maxOccurs - 1;
12971 int minOccurs =
12972 particle->minOccurs < 1 ? 0 : particle->minOccurs - 1;
12973
12974 /*
12975 * use a counter to keep track of the number of transitions
12976 * which went through the choice.
12977 */
12978 counter =
12979 xmlAutomataNewCounter(pctxt->am, minOccurs, maxOccurs);
12980 hop = xmlAutomataNewState(pctxt->am);
12981 base = xmlAutomataNewState(pctxt->am);
12982
12983 sub = particle->children->children;
12984 while (sub != NULL((void*)0)) {
12985 pctxt->state = base;
12986 tmp2 = xmlSchemaBuildAContentModel(pctxt,
12987 (xmlSchemaParticlePtr) sub);
12988 if (tmp2 == 1) ret = 1;
12989 xmlAutomataNewEpsilon(pctxt->am, pctxt->state, hop);
12990 sub = sub->next;
12991 }
12992 xmlAutomataNewEpsilon(pctxt->am, start, base);
12993 xmlAutomataNewCountedTrans(pctxt->am, hop, base, counter);
12994 xmlAutomataNewCounterTrans(pctxt->am, hop, end, counter);
12995 if (ret == 1)
12996 xmlAutomataNewEpsilon(pctxt->am, base, end);
12997 }
12998 if (particle->minOccurs == 0) {
12999 xmlAutomataNewEpsilon(pctxt->am, start, end);
13000 ret = 1;
13001 }
13002 pctxt->state = end;
13003 break;
13004 }
13005 case XML_SCHEMA_TYPE_ALL:{
13006 xmlAutomataStatePtr start, tmp;
13007 xmlSchemaParticlePtr sub;
13008 xmlSchemaElementPtr elemDecl;
13009
13010 ret = 1;
13011
13012 sub = (xmlSchemaParticlePtr) particle->children->children;
13013 if (sub == NULL((void*)0))
13014 break;
13015
13016 ret = 0;
13017
13018 start = pctxt->state;
13019 tmp = xmlAutomataNewState(pctxt->am);
13020 xmlAutomataNewEpsilon(pctxt->am, pctxt->state, tmp);
13021 pctxt->state = tmp;
13022 while (sub != NULL((void*)0)) {
13023 pctxt->state = tmp;
13024
13025 elemDecl = (xmlSchemaElementPtr) sub->children;
13026 if (elemDecl == NULL((void*)0)) {
13027 PERROR_INT("xmlSchemaBuildAContentModel",xmlSchemaInternalErr((xmlSchemaAbstractCtxtPtr) pctxt, "xmlSchemaBuildAContentModel"
, "<element> particle has no term");
13028 "<element> particle has no term")xmlSchemaInternalErr((xmlSchemaAbstractCtxtPtr) pctxt, "xmlSchemaBuildAContentModel"
, "<element> particle has no term");
;
13029 return(ret);
13030 };
13031 /*
13032 * NOTE: The {max occurs} of all the particles in the
13033 * {particles} of the group must be 0 or 1; this is
13034 * already ensured during the parse of the content of
13035 * <all>.
13036 */
13037 if (elemDecl->flags & XML_SCHEMAS_ELEM_SUBST_GROUP_HEAD1 << 17) {
13038 int counter;
13039
13040 /*
13041 * This is an abstract group, we need to share
13042 * the same counter for all the element transitions
13043 * derived from the group
13044 */
13045 counter = xmlAutomataNewCounter(pctxt->am,
13046 sub->minOccurs, sub->maxOccurs);
13047 xmlSchemaBuildContentModelForSubstGroup(pctxt,
13048 sub, counter, pctxt->state);
13049 } else {
13050 if ((sub->minOccurs == 1) &&
13051 (sub->maxOccurs == 1)) {
13052 xmlAutomataNewOnceTrans2(pctxt->am, pctxt->state,
13053 pctxt->state,
13054 elemDecl->name,
13055 elemDecl->targetNamespace,
13056 1, 1, elemDecl);
13057 } else if ((sub->minOccurs == 0) &&
13058 (sub->maxOccurs == 1)) {
13059
13060 xmlAutomataNewCountTrans2(pctxt->am, pctxt->state,
13061 pctxt->state,
13062 elemDecl->name,
13063 elemDecl->targetNamespace,
13064 0,
13065 1,
13066 elemDecl);
13067 }
13068 }
13069 sub = (xmlSchemaParticlePtr) sub->next;
13070 }
13071 pctxt->state =
13072 xmlAutomataNewAllTrans(pctxt->am, pctxt->state, NULL((void*)0), 0);
13073 if (particle->minOccurs == 0) {
13074 xmlAutomataNewEpsilon(pctxt->am, start, pctxt->state);
13075 ret = 1;
13076 }
13077 break;
13078 }
13079 case XML_SCHEMA_TYPE_GROUP:
13080 /*
13081 * If we hit a model group definition, then this means that
13082 * it was empty, thus was not substituted for the containing
13083 * model group. Just do nothing in this case.
13084 * TODO: But the group should be substituted and not occur at
13085 * all in the content model at this point. Fix this.
13086 */
13087 ret = 1;
13088 break;
13089 default:
13090 xmlSchemaInternalErr2(ACTXT_CAST(xmlSchemaAbstractCtxtPtr) pctxt,
13091 "xmlSchemaBuildAContentModel",
13092 "found unexpected term of type '%s' in content model",
13093 WXS_ITEM_TYPE_NAME(particle->children)xmlSchemaGetComponentTypeStr((xmlSchemaBasicItemPtr) (particle
->children))
, NULL((void*)0));
13094 return(ret);
13095 }
13096 return(ret);
13097}
13098
13099/**
13100 * xmlSchemaBuildContentModel:
13101 * @ctxt: the schema parser context
13102 * @type: the complex type definition
13103 * @name: the element name
13104 *
13105 * Builds the content model of the complex type.
13106 */
13107static void
13108xmlSchemaBuildContentModel(xmlSchemaTypePtr type,
13109 xmlSchemaParserCtxtPtr ctxt)
13110{
13111 if ((type->type != XML_SCHEMA_TYPE_COMPLEX) ||
13112 (type->contModel != NULL((void*)0)) ||
13113 ((type->contentType != XML_SCHEMA_CONTENT_ELEMENTS) &&
13114 (type->contentType != XML_SCHEMA_CONTENT_MIXED)))
13115 return;
13116
13117 ctxt->am = NULL((void*)0);
13118 ctxt->am = xmlNewAutomata();
13119 if (ctxt->am == NULL((void*)0)) {
13120 xmlGenericError(*__xmlGenericError())(xmlGenericErrorContext(*__xmlGenericErrorContext()),
13121 "Cannot create automata for complex type %s\n", type->name);
13122 return;
13123 }
13124 ctxt->state = xmlAutomataGetInitState(ctxt->am);
13125 /*
13126 * Build the automaton.
13127 */
13128 xmlSchemaBuildAContentModel(ctxt, WXS_TYPE_PARTICLE(type)(xmlSchemaParticlePtr) (type)->subtypes);
13129 xmlAutomataSetFinalState(ctxt->am, ctxt->state);
13130 type->contModel = xmlAutomataCompile(ctxt->am);
13131 if (type->contModel == NULL((void*)0)) {
13132 xmlSchemaPCustomErr(ctxt,
13133 XML_SCHEMAP_INTERNAL,
13134 WXS_BASIC_CAST(xmlSchemaBasicItemPtr) type, type->node,
13135 "Failed to compile the content model", NULL((void*)0));
13136 } else if (xmlRegexpIsDeterminist(type->contModel) != 1) {
13137 xmlSchemaPCustomErr(ctxt,
13138 XML_SCHEMAP_NOT_DETERMINISTIC,
13139 /* XML_SCHEMAS_ERR_NOTDETERMINIST, */
13140 WXS_BASIC_CAST(xmlSchemaBasicItemPtr) type, type->node,
13141 "The content model is not determinist", NULL((void*)0));
13142 } else {
13143 }
13144 ctxt->state = NULL((void*)0);
13145 xmlFreeAutomata(ctxt->am);
13146 ctxt->am = NULL((void*)0);
13147}
13148
13149/**
13150 * xmlSchemaResolveElementReferences:
13151 * @elem: the schema element context
13152 * @ctxt: the schema parser context
13153 *
13154 * Resolves the references of an element declaration
13155 * or particle, which has an element declaration as it's
13156 * term.
13157 */
13158static void
13159xmlSchemaResolveElementReferences(xmlSchemaElementPtr elemDecl,
13160 xmlSchemaParserCtxtPtr ctxt)
13161{
13162 if ((ctxt == NULL((void*)0)) || (elemDecl == NULL((void*)0)) ||
13163 ((elemDecl != NULL((void*)0)) &&
13164 (elemDecl->flags & XML_SCHEMAS_ELEM_INTERNAL_RESOLVED1 << 8)))
13165 return;
13166 elemDecl->flags |= XML_SCHEMAS_ELEM_INTERNAL_RESOLVED1 << 8;
13167
13168 if ((elemDecl->subtypes == NULL((void*)0)) && (elemDecl->namedType != NULL((void*)0))) {
13169 xmlSchemaTypePtr type;
13170
13171 /* (type definition) ... otherwise the type definition `resolved`
13172 * to by the `actual value` of the type [attribute] ...
13173 */
13174 type = xmlSchemaGetType(ctxt->schema, elemDecl->namedType,
13175 elemDecl->namedTypeNs);
13176 if (type == NULL((void*)0)) {
13177 xmlSchemaPResCompAttrErr(ctxt,
13178 XML_SCHEMAP_SRC_RESOLVE,
13179 WXS_BASIC_CAST(xmlSchemaBasicItemPtr) elemDecl, elemDecl->node,
13180 "type", elemDecl->namedType, elemDecl->namedTypeNs,
13181 XML_SCHEMA_TYPE_BASIC, "type definition");
13182 } else
13183 elemDecl->subtypes = type;
13184 }
13185 if (elemDecl->substGroup != NULL((void*)0)) {
13186 xmlSchemaElementPtr substHead;
13187
13188 /*
13189 * FIXME TODO: Do we need a new field in _xmlSchemaElement for
13190 * substitutionGroup?
13191 */
13192 substHead = xmlSchemaGetElem(ctxt->schema, elemDecl->substGroup,
13193 elemDecl->substGroupNs);
13194 if (substHead == NULL((void*)0)) {
13195 xmlSchemaPResCompAttrErr(ctxt,
13196 XML_SCHEMAP_SRC_RESOLVE,
13197 WXS_BASIC_CAST(xmlSchemaBasicItemPtr) elemDecl, NULL((void*)0),
13198 "substitutionGroup", elemDecl->substGroup,
13199 elemDecl->substGroupNs, XML_SCHEMA_TYPE_ELEMENT, NULL((void*)0));
13200 } else {
13201 xmlSchemaResolveElementReferences(substHead, ctxt);
13202 /*
13203 * Set the "substitution group affiliation".
13204 * NOTE that now we use the "refDecl" field for this.
13205 */
13206 WXS_SUBST_HEAD(elemDecl)(elemDecl)->refDecl = substHead;
13207 /*
13208 * The type definitions is set to:
13209 * SPEC "...the {type definition} of the element
13210 * declaration `resolved` to by the `actual value`
13211 * of the substitutionGroup [attribute], if present"
13212 */
13213 if (elemDecl->subtypes == NULL((void*)0)) {
13214 if (substHead->subtypes == NULL((void*)0)) {
13215 /*
13216 * This can happen with self-referencing substitution
13217 * groups. The cycle will be detected later, but we have
13218 * to set subtypes to avoid null-pointer dereferences.
13219 */
13220 elemDecl->subtypes = xmlSchemaGetBuiltInType(
13221 XML_SCHEMAS_ANYTYPE);
13222 } else {
13223 elemDecl->subtypes = substHead->subtypes;
13224 }
13225 }
13226 }
13227 }
13228 /*
13229 * SPEC "The definition of anyType serves as the default type definition
13230 * for element declarations whose XML representation does not specify one."
13231 */
13232 if ((elemDecl->subtypes == NULL((void*)0)) &&
13233 (elemDecl->namedType == NULL((void*)0)) &&
13234 (elemDecl->substGroup == NULL((void*)0)))
13235 elemDecl->subtypes = xmlSchemaGetBuiltInType(XML_SCHEMAS_ANYTYPE);
13236}
13237
13238/**
13239 * xmlSchemaResolveUnionMemberTypes:
13240 * @ctxt: the schema parser context
13241 * @type: the schema simple type definition
13242 *
13243 * Checks and builds the "member type definitions" property of the union
13244 * simple type. This handles part (1), part (2) is done in
13245 * xmlSchemaFinishMemberTypeDefinitionsProperty()
13246 *
13247 * Returns -1 in case of an internal error, 0 otherwise.
13248 */
13249static int
13250xmlSchemaResolveUnionMemberTypes(xmlSchemaParserCtxtPtr ctxt,
13251 xmlSchemaTypePtr type)
13252{
13253
13254 xmlSchemaTypeLinkPtr link, lastLink, newLink;
13255 xmlSchemaTypePtr memberType;
13256
13257 /*
13258 * SPEC (1) "If the <union> alternative is chosen, then [Definition:]
13259 * define the explicit members as the type definitions `resolved`
13260 * to by the items in the `actual value` of the memberTypes [attribute],
13261 * if any, followed by the type definitions corresponding to the
13262 * <simpleType>s among the [children] of <union>, if any."
13263 */
13264 /*
13265 * Resolve references.
13266 */
13267 link = type->memberTypes;
13268 lastLink = NULL((void*)0);
13269 while (link != NULL((void*)0)) {
13270 const xmlChar *name, *nsName;
13271
13272 name = ((xmlSchemaQNameRefPtr) link->type)->name;
13273 nsName = ((xmlSchemaQNameRefPtr) link->type)->targetNamespace;
13274
13275 memberType = xmlSchemaGetType(ctxt->schema, name, nsName);
13276 if ((memberType == NULL((void*)0)) || (! WXS_IS_SIMPLE(memberType)((memberType->type == XML_SCHEMA_TYPE_SIMPLE) || ((memberType
->type == XML_SCHEMA_TYPE_BASIC) && (memberType->
builtInType != XML_SCHEMAS_ANYTYPE)))
)) {
13277 xmlSchemaPResCompAttrErr(ctxt, XML_SCHEMAP_SRC_RESOLVE,
13278 WXS_BASIC_CAST(xmlSchemaBasicItemPtr) type, type->node, "memberTypes",
13279 name, nsName, XML_SCHEMA_TYPE_SIMPLE, NULL((void*)0));
13280 /*
13281 * Remove the member type link.
13282 */
13283 if (lastLink == NULL((void*)0))
13284 type->memberTypes = link->next;
13285 else
13286 lastLink->next = link->next;
13287 newLink = link;
13288 link = link->next;
13289 xmlFree(newLink);
13290 } else {
13291 link->type = memberType;
13292 lastLink = link;
13293 link = link->next;
13294 }
13295 }
13296 /*
13297 * Add local simple types,
13298 */
13299 memberType = type->subtypes;
13300 while (memberType != NULL((void*)0)) {
13301 link = (xmlSchemaTypeLinkPtr) xmlMalloc(sizeof(xmlSchemaTypeLink));
13302 if (link == NULL((void*)0)) {
13303 xmlSchemaPErrMemory(ctxt, "allocating a type link", NULL((void*)0));
13304 return (-1);
13305 }
13306 link->type = memberType;
13307 link->next = NULL((void*)0);
13308 if (lastLink == NULL((void*)0))
13309 type->memberTypes = link;
13310 else
13311 lastLink->next = link;
13312 lastLink = link;
13313 memberType = memberType->next;
13314 }
13315 return (0);
13316}
13317
13318/**
13319 * xmlSchemaIsDerivedFromBuiltInType:
13320 * @ctxt: the schema parser context
13321 * @type: the type definition
13322 * @valType: the value type
13323 *
13324 *
13325 * Returns 1 if the type has the given value type, or
13326 * is derived from such a type.
13327 */
13328static int
13329xmlSchemaIsDerivedFromBuiltInType(xmlSchemaTypePtr type, int valType)
13330{
13331 if (type == NULL((void*)0))
13332 return (0);
13333 if (WXS_IS_COMPLEX(type)(((type)->type == XML_SCHEMA_TYPE_COMPLEX) || ((type)->
builtInType == XML_SCHEMAS_ANYTYPE))
)
13334 return (0);
13335 if (type->type == XML_SCHEMA_TYPE_BASIC) {
13336 if (type->builtInType == valType)
13337 return(1);
13338 if ((type->builtInType == XML_SCHEMAS_ANYSIMPLETYPE) ||
13339 (type->builtInType == XML_SCHEMAS_ANYTYPE))
13340 return (0);
13341 return(xmlSchemaIsDerivedFromBuiltInType(type->subtypes, valType));
13342 }
13343 return(xmlSchemaIsDerivedFromBuiltInType(type->subtypes, valType));
13344}
13345
13346#if 0
13347/**
13348 * xmlSchemaIsDerivedFromBuiltInType:
13349 * @ctxt: the schema parser context
13350 * @type: the type definition
13351 * @valType: the value type
13352 *
13353 *
13354 * Returns 1 if the type has the given value type, or
13355 * is derived from such a type.
13356 */
13357static int
13358xmlSchemaIsUserDerivedFromBuiltInType(xmlSchemaTypePtr type, int valType)
13359{
13360 if (type == NULL((void*)0))
13361 return (0);
13362 if (WXS_IS_COMPLEX(type)(((type)->type == XML_SCHEMA_TYPE_COMPLEX) || ((type)->
builtInType == XML_SCHEMAS_ANYTYPE))
)
13363 return (0);
13364 if (type->type == XML_SCHEMA_TYPE_BASIC) {
13365 if (type->builtInType == valType)
13366 return(1);
13367 return (0);
13368 } else
13369 return(xmlSchemaIsDerivedFromBuiltInType(type->subtypes, valType));
13370
13371 return (0);
13372}
13373
13374static xmlSchemaTypePtr
13375xmlSchemaQueryBuiltInType(xmlSchemaTypePtr type)
13376{
13377 if (type == NULL((void*)0))
13378 return (NULL((void*)0));
13379 if (WXS_IS_COMPLEX(type)(((type)->type == XML_SCHEMA_TYPE_COMPLEX) || ((type)->
builtInType == XML_SCHEMAS_ANYTYPE))
)
13380 return (NULL((void*)0));
13381 if (type->type == XML_SCHEMA_TYPE_BASIC)
13382 return(type);
13383 return(xmlSchemaQueryBuiltInType(type->subtypes));
13384}
13385#endif
13386
13387/**
13388 * xmlSchemaGetPrimitiveType:
13389 * @type: the simpleType definition
13390 *
13391 * Returns the primitive type of the given type or
13392 * NULL in case of error.
13393 */
13394static xmlSchemaTypePtr
13395xmlSchemaGetPrimitiveType(xmlSchemaTypePtr type)
13396{
13397
13398 while (type != NULL((void*)0)) {
13399 /*
13400 * Note that anySimpleType is actually not a primitive type
13401 * but we need that here.
13402 */
13403 if ((type->builtInType == XML_SCHEMAS_ANYSIMPLETYPE) ||
13404 (type->flags & XML_SCHEMAS_TYPE_BUILTIN_PRIMITIVE1 << 14))
13405 return (type);
13406 type = type->baseType;
13407 }
13408
13409 return (NULL((void*)0));
13410}
13411
13412#if 0
13413/**
13414 * xmlSchemaGetBuiltInTypeAncestor:
13415 * @type: the simpleType definition
13416 *
13417 * Returns the primitive type of the given type or
13418 * NULL in case of error.
13419 */
13420static xmlSchemaTypePtr
13421xmlSchemaGetBuiltInTypeAncestor(xmlSchemaTypePtr type)
13422{
13423 if (WXS_IS_LIST(type)(type->flags & 1 << 6) || WXS_IS_UNION(type)(type->flags & 1 << 7))
13424 return (0);
13425 while (type != NULL((void*)0)) {
13426 if (type->type == XML_SCHEMA_TYPE_BASIC)
13427 return (type);
13428 type = type->baseType;
13429 }
13430
13431 return (NULL((void*)0));
13432}
13433#endif
13434
13435/**
13436 * xmlSchemaCloneWildcardNsConstraints:
13437 * @ctxt: the schema parser context
13438 * @dest: the destination wildcard
13439 * @source: the source wildcard
13440 *
13441 * Clones the namespace constraints of source
13442 * and assigns them to dest.
13443 * Returns -1 on internal error, 0 otherwise.
13444 */
13445static int
13446xmlSchemaCloneWildcardNsConstraints(xmlSchemaParserCtxtPtr ctxt,
13447 xmlSchemaWildcardPtr dest,
13448 xmlSchemaWildcardPtr source)
13449{
13450 xmlSchemaWildcardNsPtr cur, tmp, last;
13451
13452 if ((source == NULL((void*)0)) || (dest == NULL((void*)0)))
13453 return(-1);
13454 dest->any = source->any;
13455 cur = source->nsSet;
13456 last = NULL((void*)0);
13457 while (cur != NULL((void*)0)) {
13458 tmp = xmlSchemaNewWildcardNsConstraint(ctxt);
13459 if (tmp == NULL((void*)0))
13460 return(-1);
13461 tmp->value = cur->value;
13462 if (last == NULL((void*)0))
13463 dest->nsSet = tmp;
13464 else
13465 last->next = tmp;
13466 last = tmp;
13467 cur = cur->next;
13468 }
13469 if (dest->negNsSet != NULL((void*)0))
13470 xmlSchemaFreeWildcardNsSet(dest->negNsSet);
13471 if (source->negNsSet != NULL((void*)0)) {
13472 dest->negNsSet = xmlSchemaNewWildcardNsConstraint(ctxt);
13473 if (dest->negNsSet == NULL((void*)0))
13474 return(-1);
13475 dest->negNsSet->value = source->negNsSet->value;
13476 } else
13477 dest->negNsSet = NULL((void*)0);
13478 return(0);
13479}
13480
13481/**
13482 * xmlSchemaUnionWildcards:
13483 * @ctxt: the schema parser context
13484 * @completeWild: the first wildcard
13485 * @curWild: the second wildcard
13486 *
13487 * Unions the namespace constraints of the given wildcards.
13488 * @completeWild will hold the resulting union.
13489 * Returns a positive error code on failure, -1 in case of an
13490 * internal error, 0 otherwise.
13491 */
13492static int
13493xmlSchemaUnionWildcards(xmlSchemaParserCtxtPtr ctxt,
13494 xmlSchemaWildcardPtr completeWild,
13495 xmlSchemaWildcardPtr curWild)
13496{
13497 xmlSchemaWildcardNsPtr cur, curB, tmp;
13498
13499 /*
13500 * 1 If O1 and O2 are the same value, then that value must be the
13501 * value.
13502 */
13503 if ((completeWild->any == curWild->any) &&
13504 ((completeWild->nsSet == NULL((void*)0)) == (curWild->nsSet == NULL((void*)0))) &&
13505 ((completeWild->negNsSet == NULL((void*)0)) == (curWild->negNsSet == NULL((void*)0)))) {
13506
13507 if ((completeWild->negNsSet == NULL((void*)0)) ||
13508 (completeWild->negNsSet->value == curWild->negNsSet->value)) {
13509
13510 if (completeWild->nsSet != NULL((void*)0)) {
13511 int found = 0;
13512
13513 /*
13514 * Check equality of sets.
13515 */
13516 cur = completeWild->nsSet;
13517 while (cur != NULL((void*)0)) {
13518 found = 0;
13519 curB = curWild->nsSet;
13520 while (curB != NULL((void*)0)) {
13521 if (cur->value == curB->value) {
13522 found = 1;
13523 break;
13524 }
13525 curB = curB->next;
13526 }
13527 if (!found)
13528 break;
13529 cur = cur->next;
13530 }
13531 if (found)
13532 return(0);
13533 } else
13534 return(0);
13535 }
13536 }
13537 /*
13538 * 2 If either O1 or O2 is any, then any must be the value
13539 */
13540 if (completeWild->any != curWild->any) {
13541 if (completeWild->any == 0) {
13542 completeWild->any = 1;
13543 if (completeWild->nsSet != NULL((void*)0)) {
13544 xmlSchemaFreeWildcardNsSet(completeWild->nsSet);
13545 completeWild->nsSet = NULL((void*)0);
13546 }
13547 if (completeWild->negNsSet != NULL((void*)0)) {
13548 xmlFree(completeWild->negNsSet);
13549 completeWild->negNsSet = NULL((void*)0);
13550 }
13551 }
13552 return (0);
13553 }
13554 /*
13555 * 3 If both O1 and O2 are sets of (namespace names or `absent`),
13556 * then the union of those sets must be the value.
13557 */
13558 if ((completeWild->nsSet != NULL((void*)0)) && (curWild->nsSet != NULL((void*)0))) {
13559 int found;
13560 xmlSchemaWildcardNsPtr start;
13561
13562 cur = curWild->nsSet;
13563 start = completeWild->nsSet;
13564 while (cur != NULL((void*)0)) {
13565 found = 0;
13566 curB = start;
13567 while (curB != NULL((void*)0)) {
13568 if (cur->value == curB->value) {
13569 found = 1;
13570 break;
13571 }
13572 curB = curB->next;
13573 }
13574 if (!found) {
13575 tmp = xmlSchemaNewWildcardNsConstraint(ctxt);
13576 if (tmp == NULL((void*)0))
13577 return (-1);
13578 tmp->value = cur->value;
13579 tmp->next = completeWild->nsSet;
13580 completeWild->nsSet = tmp;
13581 }
13582 cur = cur->next;
13583 }
13584
13585 return(0);
13586 }
13587 /*
13588 * 4 If the two are negations of different values (namespace names
13589 * or `absent`), then a pair of not and `absent` must be the value.
13590 */
13591 if ((completeWild->negNsSet != NULL((void*)0)) &&
13592 (curWild->negNsSet != NULL((void*)0)) &&
13593 (completeWild->negNsSet->value != curWild->negNsSet->value)) {
13594 completeWild->negNsSet->value = NULL((void*)0);
13595
13596 return(0);
13597 }
13598 /*
13599 * 5.
13600 */
13601 if (((completeWild->negNsSet != NULL((void*)0)) &&
13602 (completeWild->negNsSet->value != NULL((void*)0)) &&
13603 (curWild->nsSet != NULL((void*)0))) ||
13604 ((curWild->negNsSet != NULL((void*)0)) &&
13605 (curWild->negNsSet->value != NULL((void*)0)) &&
13606 (completeWild->nsSet != NULL((void*)0)))) {
13607
13608 int nsFound, absentFound = 0;
13609
13610 if (completeWild->nsSet != NULL((void*)0)) {
13611 cur = completeWild->nsSet;
13612 curB = curWild->negNsSet;
13613 } else {
13614 cur = curWild->nsSet;
13615 curB = completeWild->negNsSet;
13616 }
13617 nsFound = 0;
13618 while (cur != NULL((void*)0)) {
13619 if (cur->value == NULL((void*)0))
13620 absentFound = 1;
13621 else if (cur->value == curB->value)
13622 nsFound = 1;
13623 if (nsFound && absentFound)
13624 break;
13625 cur = cur->next;
13626 }
13627
13628 if (nsFound && absentFound) {
13629 /*
13630 * 5.1 If the set S includes both the negated namespace
13631 * name and `absent`, then any must be the value.
13632 */
13633 completeWild->any = 1;
13634 if (completeWild->nsSet != NULL((void*)0)) {
13635 xmlSchemaFreeWildcardNsSet(completeWild->nsSet);
13636 completeWild->nsSet = NULL((void*)0);
13637 }
13638 if (completeWild->negNsSet != NULL((void*)0)) {
13639 xmlFree(completeWild->negNsSet);
13640 completeWild->negNsSet = NULL((void*)0);
13641 }
13642 } else if (nsFound && (!absentFound)) {
13643 /*
13644 * 5.2 If the set S includes the negated namespace name
13645 * but not `absent`, then a pair of not and `absent` must
13646 * be the value.
13647 */
13648 if (completeWild->nsSet != NULL((void*)0)) {
13649 xmlSchemaFreeWildcardNsSet(completeWild->nsSet);
13650 completeWild->nsSet = NULL((void*)0);
13651 }
13652 if (completeWild->negNsSet == NULL((void*)0)) {
13653 completeWild->negNsSet = xmlSchemaNewWildcardNsConstraint(ctxt);
13654 if (completeWild->negNsSet == NULL((void*)0))
13655 return (-1);
13656 }
13657 completeWild->negNsSet->value = NULL((void*)0);
13658 } else if ((!nsFound) && absentFound) {
13659 /*
13660 * 5.3 If the set S includes `absent` but not the negated
13661 * namespace name, then the union is not expressible.
13662 */
13663 xmlSchemaPErr(ctxt, completeWild->node,
13664 XML_SCHEMAP_UNION_NOT_EXPRESSIBLE,
13665 "The union of the wildcard is not expressible.\n",
13666 NULL((void*)0), NULL((void*)0));
13667 return(XML_SCHEMAP_UNION_NOT_EXPRESSIBLE);
13668 } else if ((!nsFound) && (!absentFound)) {
13669 /*
13670 * 5.4 If the set S does not include either the negated namespace
13671 * name or `absent`, then whichever of O1 or O2 is a pair of not
13672 * and a namespace name must be the value.
13673 */
13674 if (completeWild->negNsSet == NULL((void*)0)) {
13675 if (completeWild->nsSet != NULL((void*)0)) {
13676 xmlSchemaFreeWildcardNsSet(completeWild->nsSet);
13677 completeWild->nsSet = NULL((void*)0);
13678 }
13679 completeWild->negNsSet = xmlSchemaNewWildcardNsConstraint(ctxt);
13680 if (completeWild->negNsSet == NULL((void*)0))
13681 return (-1);
13682 completeWild->negNsSet->value = curWild->negNsSet->value;
13683 }
13684 }
13685 return (0);
13686 }
13687 /*
13688 * 6.
13689 */
13690 if (((completeWild->negNsSet != NULL((void*)0)) &&
13691 (completeWild->negNsSet->value == NULL((void*)0)) &&
13692 (curWild->nsSet != NULL((void*)0))) ||
13693 ((curWild->negNsSet != NULL((void*)0)) &&
13694 (curWild->negNsSet->value == NULL((void*)0)) &&
13695 (completeWild->nsSet != NULL((void*)0)))) {
13696
13697 if (completeWild->nsSet != NULL((void*)0)) {
13698 cur = completeWild->nsSet;
13699 } else {
13700 cur = curWild->nsSet;
13701 }
13702 while (cur != NULL((void*)0)) {
13703 if (cur->value == NULL((void*)0)) {
13704 /*
13705 * 6.1 If the set S includes `absent`, then any must be the
13706 * value.
13707 */
13708 completeWild->any = 1;
13709 if (completeWild->nsSet != NULL((void*)0)) {
13710 xmlSchemaFreeWildcardNsSet(completeWild->nsSet);
13711 completeWild->nsSet = NULL((void*)0);
13712 }
13713 if (completeWild->negNsSet != NULL((void*)0)) {
13714 xmlFree(completeWild->negNsSet);
13715 completeWild->negNsSet = NULL((void*)0);
13716 }
13717 return (0);
13718 }
13719 cur = cur->next;
13720 }
13721 if (completeWild->negNsSet == NULL((void*)0)) {
13722 /*
13723 * 6.2 If the set S does not include `absent`, then a pair of not
13724 * and `absent` must be the value.
13725 */
13726 if (completeWild->nsSet != NULL((void*)0)) {
13727 xmlSchemaFreeWildcardNsSet(completeWild->nsSet);
13728 completeWild->nsSet = NULL((void*)0);
13729 }
13730 completeWild->negNsSet = xmlSchemaNewWildcardNsConstraint(ctxt);
13731 if (completeWild->negNsSet == NULL((void*)0))
13732 return (-1);
13733 completeWild->negNsSet->value = NULL((void*)0);
13734 }
13735 return (0);
13736 }
13737 return (0);
13738
13739}
13740
13741/**
13742 * xmlSchemaIntersectWildcards:
13743 * @ctxt: the schema parser context
13744 * @completeWild: the first wildcard
13745 * @curWild: the second wildcard
13746 *
13747 * Intersects the namespace constraints of the given wildcards.
13748 * @completeWild will hold the resulting intersection.
13749 * Returns a positive error code on failure, -1 in case of an
13750 * internal error, 0 otherwise.
13751 */
13752static int
13753xmlSchemaIntersectWildcards(xmlSchemaParserCtxtPtr ctxt,
13754 xmlSchemaWildcardPtr completeWild,
13755 xmlSchemaWildcardPtr curWild)
13756{
13757 xmlSchemaWildcardNsPtr cur, curB, prev, tmp;
13758
13759 /*
13760 * 1 If O1 and O2 are the same value, then that value must be the
13761 * value.
13762 */
13763 if ((completeWild->any == curWild->any) &&
13764 ((completeWild->nsSet == NULL((void*)0)) == (curWild->nsSet == NULL((void*)0))) &&
13765 ((completeWild->negNsSet == NULL((void*)0)) == (curWild->negNsSet == NULL((void*)0)))) {
13766
13767 if ((completeWild->negNsSet == NULL((void*)0)) ||
13768 (completeWild->negNsSet->value == curWild->negNsSet->value)) {
13769
13770 if (completeWild->nsSet != NULL((void*)0)) {
13771 int found = 0;
13772
13773 /*
13774 * Check equality of sets.
13775 */
13776 cur = completeWild->nsSet;
13777 while (cur != NULL((void*)0)) {
13778 found = 0;
13779 curB = curWild->nsSet;
13780 while (curB != NULL((void*)0)) {
13781 if (cur->value == curB->value) {
13782 found = 1;
13783 break;
13784 }
13785 curB = curB->next;
13786 }
13787 if (!found)
13788 break;
13789 cur = cur->next;
13790 }
13791 if (found)
13792 return(0);
13793 } else
13794 return(0);
13795 }
13796 }
13797 /*
13798 * 2 If either O1 or O2 is any, then the other must be the value.
13799 */
13800 if ((completeWild->any != curWild->any) && (completeWild->any)) {
13801 if (xmlSchemaCloneWildcardNsConstraints(ctxt, completeWild, curWild) == -1)
13802 return(-1);
13803 return(0);
13804 }
13805 /*
13806 * 3 If either O1 or O2 is a pair of not and a value (a namespace
13807 * name or `absent`) and the other is a set of (namespace names or
13808 * `absent`), then that set, minus the negated value if it was in
13809 * the set, minus `absent` if it was in the set, must be the value.
13810 */
13811 if (((completeWild->negNsSet != NULL((void*)0)) && (curWild->nsSet != NULL((void*)0))) ||
13812 ((curWild->negNsSet != NULL((void*)0)) && (completeWild->nsSet != NULL((void*)0)))) {
13813 const xmlChar *neg;
13814
13815 if (completeWild->nsSet == NULL((void*)0)) {
13816 neg = completeWild->negNsSet->value;
13817 if (xmlSchemaCloneWildcardNsConstraints(ctxt, completeWild, curWild) == -1)
13818 return(-1);
13819 } else
13820 neg = curWild->negNsSet->value;
13821 /*
13822 * Remove absent and negated.
13823 */
13824 prev = NULL((void*)0);
13825 cur = completeWild->nsSet;
13826 while (cur != NULL((void*)0)) {
13827 if (cur->value == NULL((void*)0)) {
13828 if (prev == NULL((void*)0))
13829 completeWild->nsSet = cur->next;
13830 else
13831 prev->next = cur->next;
13832 xmlFree(cur);
13833 break;
13834 }
13835 prev = cur;
13836 cur = cur->next;
13837 }
13838 if (neg != NULL((void*)0)) {
13839 prev = NULL((void*)0);
13840 cur = completeWild->nsSet;
13841 while (cur != NULL((void*)0)) {
13842 if (cur->value == neg) {
13843 if (prev == NULL((void*)0))
13844 completeWild->nsSet = cur->next;
13845 else
13846 prev->next = cur->next;
13847 xmlFree(cur);
13848 break;
13849 }
13850 prev = cur;
13851 cur = cur->next;
13852 }
13853 }
13854
13855 return(0);
13856 }
13857 /*
13858 * 4 If both O1 and O2 are sets of (namespace names or `absent`),
13859 * then the intersection of those sets must be the value.
13860 */
13861 if ((completeWild->nsSet != NULL((void*)0)) && (curWild->nsSet != NULL((void*)0))) {
13862 int found;
13863
13864 cur = completeWild->nsSet;
13865 prev = NULL((void*)0);
13866 while (cur != NULL((void*)0)) {
13867 found = 0;
13868 curB = curWild->nsSet;
13869 while (curB != NULL((void*)0)) {
13870 if (cur->value == curB->value) {
13871 found = 1;
13872 break;
13873 }
13874 curB = curB->next;
13875 }
13876 if (!found) {
13877 if (prev == NULL((void*)0))
13878 completeWild->nsSet = cur->next;
13879 else
13880 prev->next = cur->next;
13881 tmp = cur->next;
13882 xmlFree(cur);
13883 cur = tmp;
13884 continue;
13885 }
13886 prev = cur;
13887 cur = cur->next;
13888 }
13889
13890 return(0);
13891 }
13892 /* 5 If the two are negations of different namespace names,
13893 * then the intersection is not expressible
13894 */
13895 if ((completeWild->negNsSet != NULL((void*)0)) &&
13896 (curWild->negNsSet != NULL((void*)0)) &&
13897 (completeWild->negNsSet->value != curWild->negNsSet->value) &&
13898 (completeWild->negNsSet->value != NULL((void*)0)) &&
13899 (curWild->negNsSet->value != NULL((void*)0))) {
13900
13901 xmlSchemaPErr(ctxt, completeWild->node, XML_SCHEMAP_INTERSECTION_NOT_EXPRESSIBLE,
13902 "The intersection of the wildcard is not expressible.\n",
13903 NULL((void*)0), NULL((void*)0));
13904 return(XML_SCHEMAP_INTERSECTION_NOT_EXPRESSIBLE);
13905 }
13906 /*
13907 * 6 If the one is a negation of a namespace name and the other
13908 * is a negation of `absent`, then the one which is the negation
13909 * of a namespace name must be the value.
13910 */
13911 if ((completeWild->negNsSet != NULL((void*)0)) && (curWild->negNsSet != NULL((void*)0)) &&
13912 (completeWild->negNsSet->value != curWild->negNsSet->value) &&
13913 (completeWild->negNsSet->value == NULL((void*)0))) {
13914 completeWild->negNsSet->value = curWild->negNsSet->value;
13915 }
13916 return(0);
13917}
13918
13919/**
13920 * xmlSchemaIsWildcardNsConstraintSubset:
13921 * @ctxt: the schema parser context
13922 * @sub: the first wildcard
13923 * @super: the second wildcard
13924 *
13925 * Schema Component Constraint: Wildcard Subset (cos-ns-subset)
13926 *
13927 * Returns 0 if the namespace constraint of @sub is an intensional
13928 * subset of @super, 1 otherwise.
13929 */
13930static int
13931xmlSchemaCheckCOSNSSubset(xmlSchemaWildcardPtr sub,
13932 xmlSchemaWildcardPtr super)
13933{
13934 /*
13935 * 1 super must be any.
13936 */
13937 if (super->any)
13938 return (0);
13939 /*
13940 * 2.1 sub must be a pair of not and a namespace name or `absent`.
13941 * 2.2 super must be a pair of not and the same value.
13942 */
13943 if ((sub->negNsSet != NULL((void*)0)) &&
13944 (super->negNsSet != NULL((void*)0)) &&
13945 (sub->negNsSet->value == super->negNsSet->value))
13946 return (0);
13947 /*
13948 * 3.1 sub must be a set whose members are either namespace names or `absent`.
13949 */
13950 if (sub->nsSet != NULL((void*)0)) {
13951 /*
13952 * 3.2.1 super must be the same set or a superset thereof.
13953 */
13954 if (super->nsSet != NULL((void*)0)) {
13955 xmlSchemaWildcardNsPtr cur, curB;
13956 int found = 0;
13957
13958 cur = sub->nsSet;
13959 while (cur != NULL((void*)0)) {
13960 found = 0;
13961 curB = super->nsSet;
13962 while (curB != NULL((void*)0)) {
13963 if (cur->value == curB->value) {
13964 found = 1;
13965 break;
13966 }
13967 curB = curB->next;
13968 }
13969 if (!found)
13970 return (1);
13971 cur = cur->next;
13972 }
13973 if (found)
13974 return (0);
13975 } else if (super->negNsSet != NULL((void*)0)) {
13976 xmlSchemaWildcardNsPtr cur;
13977 /*
13978 * 3.2.2 super must be a pair of not and a namespace name or
13979 * `absent` and that value must not be in sub's set.
13980 */
13981 cur = sub->nsSet;
13982 while (cur != NULL((void*)0)) {
13983 if (cur->value == super->negNsSet->value)
13984 return (1);
13985 cur = cur->next;
13986 }
13987 return (0);
13988 }
13989 }
13990 return (1);
13991}
13992
13993static int
13994xmlSchemaGetEffectiveValueConstraint(xmlSchemaAttributeUsePtr attruse,
13995 int *fixed,
13996 const xmlChar **value,
13997 xmlSchemaValPtr *val)
13998{
13999 *fixed = 0;
14000 *value = NULL((void*)0);
14001 if (val != 0)
14002 *val = NULL((void*)0);
14003
14004 if (attruse->defValue != NULL((void*)0)) {
14005 *value = attruse->defValue;
14006 if (val != NULL((void*)0))
14007 *val = attruse->defVal;
14008 if (attruse->flags & XML_SCHEMA_ATTR_USE_FIXED1<<0)
14009 *fixed = 1;
14010 return(1);
14011 } else if ((attruse->attrDecl != NULL((void*)0)) &&
14012 (attruse->attrDecl->defValue != NULL((void*)0))) {
14013 *value = attruse->attrDecl->defValue;
14014 if (val != NULL((void*)0))
14015 *val = attruse->attrDecl->defVal;
14016 if (attruse->attrDecl->flags & XML_SCHEMAS_ATTR_FIXED1 << 9)
14017 *fixed = 1;
14018 return(1);
14019 }
14020 return(0);
14021}
14022/**
14023 * xmlSchemaCheckCVCWildcardNamespace:
14024 * @wild: the wildcard
14025 * @ns: the namespace
14026 *
14027 * Validation Rule: Wildcard allows Namespace Name
14028 * (cvc-wildcard-namespace)
14029 *
14030 * Returns 0 if the given namespace matches the wildcard,
14031 * 1 otherwise and -1 on API errors.
14032 */
14033static int
14034xmlSchemaCheckCVCWildcardNamespace(xmlSchemaWildcardPtr wild,
14035 const xmlChar* ns)
14036{
14037 if (wild == NULL((void*)0))
14038 return(-1);
14039
14040 if (wild->any)
14041 return(0);
14042 else if (wild->nsSet != NULL((void*)0)) {
14043 xmlSchemaWildcardNsPtr cur;
14044
14045 cur = wild->nsSet;
14046 while (cur != NULL((void*)0)) {
14047 if (xmlStrEqual(cur->value, ns))
14048 return(0);
14049 cur = cur->next;
14050 }
14051 } else if ((wild->negNsSet != NULL((void*)0)) && (ns != NULL((void*)0)) &&
14052 (!xmlStrEqual(wild->negNsSet->value, ns)))
14053 return(0);
14054
14055 return(1);
14056}
14057
14058#define XML_SCHEMA_ACTION_DERIVE0 0
14059#define XML_SCHEMA_ACTION_REDEFINE1 1
14060
14061#define WXS_ACTION_STR(a)((a) == 0) ? (const xmlChar *) "base" : (const xmlChar *) "redefined" \
14062((a) == XML_SCHEMA_ACTION_DERIVE0) ? (const xmlChar *) "base" : (const xmlChar *) "redefined"
14063
14064/*
14065* Schema Component Constraint:
14066* Derivation Valid (Restriction, Complex)
14067* derivation-ok-restriction (2) - (4)
14068*
14069* ATTENTION:
14070* In XML Schema 1.1 this will be:
14071* Validation Rule:
14072* Checking complex type subsumption (practicalSubsumption) (1, 2 and 3)
14073*
14074*/
14075static int
14076xmlSchemaCheckDerivationOKRestriction2to4(xmlSchemaParserCtxtPtr pctxt,
14077 int action,
14078 xmlSchemaBasicItemPtr item,
14079 xmlSchemaBasicItemPtr baseItem,
14080 xmlSchemaItemListPtr uses,
14081 xmlSchemaItemListPtr baseUses,
14082 xmlSchemaWildcardPtr wild,
14083 xmlSchemaWildcardPtr baseWild)
14084{
14085 xmlSchemaAttributeUsePtr cur = NULL((void*)0), bcur;
14086 int i, j, found; /* err = 0; */
14087 const xmlChar *bEffValue;
14088 int effFixed;
14089
14090 if (uses != NULL((void*)0)) {
14091 for (i = 0; i < uses->nbItems; i++) {
14092 cur = uses->items[i];
14093 found = 0;
14094 if (baseUses == NULL((void*)0))
14095 goto not_found;
14096 for (j = 0; j < baseUses->nbItems; j++) {
14097 bcur = baseUses->items[j];
14098 if ((WXS_ATTRUSE_DECL_NAME(cur)(((xmlSchemaAttributeUsePtr) (cur))->attrDecl)->name ==
14099 WXS_ATTRUSE_DECL_NAME(bcur)(((xmlSchemaAttributeUsePtr) (bcur))->attrDecl)->name) &&
14100 (WXS_ATTRUSE_DECL_TNS(cur)(((xmlSchemaAttributeUsePtr) (cur))->attrDecl)->targetNamespace ==
14101 WXS_ATTRUSE_DECL_TNS(bcur)(((xmlSchemaAttributeUsePtr) (bcur))->attrDecl)->targetNamespace))
14102 {
14103 /*
14104 * (2.1) "If there is an attribute use in the {attribute
14105 * uses} of the {base type definition} (call this B) whose
14106 * {attribute declaration} has the same {name} and {target
14107 * namespace}, then all of the following must be true:"
14108 */
14109 found = 1;
14110
14111 if ((cur->occurs == XML_SCHEMAS_ATTR_USE_OPTIONAL2) &&
14112 (bcur->occurs == XML_SCHEMAS_ATTR_USE_REQUIRED1))
14113 {
14114 xmlChar *str = NULL((void*)0);
14115 /*
14116 * (2.1.1) "one of the following must be true:"
14117 * (2.1.1.1) "B's {required} is false."
14118 * (2.1.1.2) "R's {required} is true."
14119 */
14120 xmlSchemaPAttrUseErr4(pctxt,
14121 XML_SCHEMAP_DERIVATION_OK_RESTRICTION_2_1_1,
14122 WXS_ITEM_NODE(item)xmlSchemaGetComponentNode((xmlSchemaBasicItemPtr) (item)), item, cur,
14123 "The 'optional' attribute use is inconsistent "
14124 "with the corresponding 'required' attribute use of "
14125 "the %s %s",
14126 WXS_ACTION_STR(action)((action) == 0) ? (const xmlChar *) "base" : (const xmlChar *
) "redefined"
,
14127 xmlSchemaGetComponentDesignation(&str, baseItem),
14128 NULL((void*)0), NULL((void*)0));
14129 FREE_AND_NULL(str)if ((str) != ((void*)0)) { xmlFree((xmlChar *) (str)); str = (
(void*)0); }
;
14130 /* err = pctxt->err; */
14131 } else if (xmlSchemaCheckCOSSTDerivedOK(ACTXT_CAST(xmlSchemaAbstractCtxtPtr) pctxt,
14132 WXS_ATTRUSE_TYPEDEF(cur)(((xmlSchemaAttributeUsePtr) ((xmlSchemaAttributeUsePtr) cur)
)->attrDecl)->subtypes
,
14133 WXS_ATTRUSE_TYPEDEF(bcur)(((xmlSchemaAttributeUsePtr) ((xmlSchemaAttributeUsePtr) bcur
))->attrDecl)->subtypes
, 0) != 0)
14134 {
14135 xmlChar *strA = NULL((void*)0), *strB = NULL((void*)0), *strC = NULL((void*)0);
14136
14137 /*
14138 * SPEC (2.1.2) "R's {attribute declaration}'s
14139 * {type definition} must be validly derived from
14140 * B's {type definition} given the empty set as
14141 * defined in Type Derivation OK (Simple) ($3.14.6)."
14142 */
14143 xmlSchemaPAttrUseErr4(pctxt,
14144 XML_SCHEMAP_DERIVATION_OK_RESTRICTION_2_1_2,
14145 WXS_ITEM_NODE(item)xmlSchemaGetComponentNode((xmlSchemaBasicItemPtr) (item)), item, cur,
14146 "The attribute declaration's %s "
14147 "is not validly derived from "
14148 "the corresponding %s of the "
14149 "attribute declaration in the %s %s",
14150 xmlSchemaGetComponentDesignation(&strA,
14151 WXS_ATTRUSE_TYPEDEF(cur)(((xmlSchemaAttributeUsePtr) ((xmlSchemaAttributeUsePtr) cur)
)->attrDecl)->subtypes
),
14152 xmlSchemaGetComponentDesignation(&strB,
14153 WXS_ATTRUSE_TYPEDEF(bcur)(((xmlSchemaAttributeUsePtr) ((xmlSchemaAttributeUsePtr) bcur
))->attrDecl)->subtypes
),
14154 WXS_ACTION_STR(action)((action) == 0) ? (const xmlChar *) "base" : (const xmlChar *
) "redefined"
,
14155 xmlSchemaGetComponentDesignation(&strC, baseItem));
14156 /* xmlSchemaGetComponentDesignation(&str, baseItem), */
14157 FREE_AND_NULL(strA)if ((strA) != ((void*)0)) { xmlFree((xmlChar *) (strA)); strA
= ((void*)0); }
;
14158 FREE_AND_NULL(strB)if ((strB) != ((void*)0)) { xmlFree((xmlChar *) (strB)); strB
= ((void*)0); }
;
14159 FREE_AND_NULL(strC)if ((strC) != ((void*)0)) { xmlFree((xmlChar *) (strC)); strC
= ((void*)0); }
;
14160 /* err = pctxt->err; */
14161 } else {
14162 /*
14163 * 2.1.3 [Definition:] Let the effective value
14164 * constraint of an attribute use be its {value
14165 * constraint}, if present, otherwise its {attribute
14166 * declaration}'s {value constraint} .
14167 */
14168 xmlSchemaGetEffectiveValueConstraint(bcur,
14169 &effFixed, &bEffValue, NULL((void*)0));
14170 /*
14171 * 2.1.3 ... one of the following must be true
14172 *
14173 * 2.1.3.1 B's `effective value constraint` is
14174 * `absent` or default.
14175 */
14176 if ((bEffValue != NULL((void*)0)) &&
14177 (effFixed == 1)) {
14178 const xmlChar *rEffValue = NULL((void*)0);
14179
14180 xmlSchemaGetEffectiveValueConstraint(bcur,
14181 &effFixed, &rEffValue, NULL((void*)0));
14182 /*
14183 * 2.1.3.2 R's `effective value constraint` is
14184 * fixed with the same string as B's.
14185 * MAYBE TODO: Compare the computed values.
14186 * Hmm, it says "same string" so
14187 * string-equality might really be sufficient.
14188 */
14189 if ((effFixed == 0) ||
14190 (! WXS_ARE_DEFAULT_STR_EQUAL(rEffValue, bEffValue)((rEffValue) == (bEffValue))))
14191 {
14192 xmlChar *str = NULL((void*)0);
14193
14194 xmlSchemaPAttrUseErr4(pctxt,
14195 XML_SCHEMAP_DERIVATION_OK_RESTRICTION_2_1_3,
14196 WXS_ITEM_NODE(item)xmlSchemaGetComponentNode((xmlSchemaBasicItemPtr) (item)), item, cur,
14197 "The effective value constraint of the "
14198 "attribute use is inconsistent with "
14199 "its correspondent in the %s %s",
14200 WXS_ACTION_STR(action)((action) == 0) ? (const xmlChar *) "base" : (const xmlChar *
) "redefined"
,
14201 xmlSchemaGetComponentDesignation(&str,
14202 baseItem),
14203 NULL((void*)0), NULL((void*)0));
14204 FREE_AND_NULL(str)if ((str) != ((void*)0)) { xmlFree((xmlChar *) (str)); str = (
(void*)0); }
;
14205 /* err = pctxt->err; */
14206 }
14207 }
14208 }
14209 break;
14210 }
14211 }
14212not_found:
14213 if (!found) {
14214 /*
14215 * (2.2) "otherwise the {base type definition} must have an
14216 * {attribute wildcard} and the {target namespace} of the
14217 * R's {attribute declaration} must be `valid` with respect
14218 * to that wildcard, as defined in Wildcard allows Namespace
14219 * Name ($3.10.4)."
14220 */
14221 if ((baseWild == NULL((void*)0)) ||
14222 (xmlSchemaCheckCVCWildcardNamespace(baseWild,
14223 (WXS_ATTRUSE_DECL(cur)((xmlSchemaAttributeUsePtr) (cur))->attrDecl)->targetNamespace) != 0))
14224 {
14225 xmlChar *str = NULL((void*)0);
14226
14227 xmlSchemaPAttrUseErr4(pctxt,
14228 XML_SCHEMAP_DERIVATION_OK_RESTRICTION_2_2,
14229 WXS_ITEM_NODE(item)xmlSchemaGetComponentNode((xmlSchemaBasicItemPtr) (item)), item, cur,
14230 "Neither a matching attribute use, "
14231 "nor a matching wildcard exists in the %s %s",
14232 WXS_ACTION_STR(action)((action) == 0) ? (const xmlChar *) "base" : (const xmlChar *
) "redefined"
,
14233 xmlSchemaGetComponentDesignation(&str, baseItem),
14234 NULL((void*)0), NULL((void*)0));
14235 FREE_AND_NULL(str)if ((str) != ((void*)0)) { xmlFree((xmlChar *) (str)); str = (
(void*)0); }
;
14236 /* err = pctxt->err; */
14237 }
14238 }
14239 }
14240 }
14241 /*
14242 * SPEC derivation-ok-restriction (3):
14243 * (3) "For each attribute use in the {attribute uses} of the {base type
14244 * definition} whose {required} is true, there must be an attribute
14245 * use with an {attribute declaration} with the same {name} and
14246 * {target namespace} as its {attribute declaration} in the {attribute
14247 * uses} of the complex type definition itself whose {required} is true.
14248 */
14249 if (baseUses != NULL((void*)0)) {
14250 for (j = 0; j < baseUses->nbItems; j++) {
14251 bcur = baseUses->items[j];
14252 if (bcur->occurs != XML_SCHEMAS_ATTR_USE_REQUIRED1)
14253 continue;
14254 found = 0;
14255 if (uses != NULL((void*)0)) {
14256 for (i = 0; i < uses->nbItems; i++) {
14257 cur = uses->items[i];
14258 if ((WXS_ATTRUSE_DECL_NAME(cur)(((xmlSchemaAttributeUsePtr) (cur))->attrDecl)->name ==
14259 WXS_ATTRUSE_DECL_NAME(bcur)(((xmlSchemaAttributeUsePtr) (bcur))->attrDecl)->name) &&
14260 (WXS_ATTRUSE_DECL_TNS(cur)(((xmlSchemaAttributeUsePtr) (cur))->attrDecl)->targetNamespace ==
14261 WXS_ATTRUSE_DECL_TNS(bcur)(((xmlSchemaAttributeUsePtr) (bcur))->attrDecl)->targetNamespace)) {
14262 found = 1;
14263 break;
14264 }
14265 }
14266 }
14267 if (!found) {
14268 xmlChar *strA = NULL((void*)0), *strB = NULL((void*)0);
14269
14270 xmlSchemaCustomErr4(ACTXT_CAST(xmlSchemaAbstractCtxtPtr) pctxt,
14271 XML_SCHEMAP_DERIVATION_OK_RESTRICTION_3,
14272 NULL((void*)0), item,
14273 "A matching attribute use for the "
14274 "'required' %s of the %s %s is missing",
14275 xmlSchemaGetComponentDesignation(&strA, bcur),
14276 WXS_ACTION_STR(action)((action) == 0) ? (const xmlChar *) "base" : (const xmlChar *
) "redefined"
,
14277 xmlSchemaGetComponentDesignation(&strB, baseItem),
14278 NULL((void*)0));
14279 FREE_AND_NULL(strA)if ((strA) != ((void*)0)) { xmlFree((xmlChar *) (strA)); strA
= ((void*)0); }
;
14280 FREE_AND_NULL(strB)if ((strB) != ((void*)0)) { xmlFree((xmlChar *) (strB)); strB
= ((void*)0); }
;
14281 }
14282 }
14283 }
14284 /*
14285 * derivation-ok-restriction (4)
14286 */
14287 if (wild != NULL((void*)0)) {
14288 /*
14289 * (4) "If there is an {attribute wildcard}, all of the
14290 * following must be true:"
14291 */
14292 if (baseWild == NULL((void*)0)) {
14293 xmlChar *str = NULL((void*)0);
14294
14295 /*
14296 * (4.1) "The {base type definition} must also have one."
14297 */
14298 xmlSchemaCustomErr4(ACTXT_CAST(xmlSchemaAbstractCtxtPtr) pctxt,
14299 XML_SCHEMAP_DERIVATION_OK_RESTRICTION_4_1,
14300 NULL((void*)0), item,
14301 "The %s has an attribute wildcard, "
14302 "but the %s %s '%s' does not have one",
14303 WXS_ITEM_TYPE_NAME(item)xmlSchemaGetComponentTypeStr((xmlSchemaBasicItemPtr) (item)),
14304 WXS_ACTION_STR(action)((action) == 0) ? (const xmlChar *) "base" : (const xmlChar *
) "redefined"
,
14305 WXS_ITEM_TYPE_NAME(baseItem)xmlSchemaGetComponentTypeStr((xmlSchemaBasicItemPtr) (baseItem
))
,
14306 xmlSchemaGetComponentQName(&str, baseItem));
14307 FREE_AND_NULL(str)if ((str) != ((void*)0)) { xmlFree((xmlChar *) (str)); str = (
(void*)0); }
;
14308 return(pctxt->err);
14309 } else if ((baseWild->any == 0) &&
14310 xmlSchemaCheckCOSNSSubset(wild, baseWild))
14311 {
14312 xmlChar *str = NULL((void*)0);
14313 /*
14314 * (4.2) "The complex type definition's {attribute wildcard}'s
14315 * {namespace constraint} must be a subset of the {base type
14316 * definition}'s {attribute wildcard}'s {namespace constraint},
14317 * as defined by Wildcard Subset ($3.10.6)."
14318 */
14319 xmlSchemaCustomErr4(ACTXT_CAST(xmlSchemaAbstractCtxtPtr) pctxt,
14320 XML_SCHEMAP_DERIVATION_OK_RESTRICTION_4_2,
14321 NULL((void*)0), item,
14322 "The attribute wildcard is not a valid "
14323 "subset of the wildcard in the %s %s '%s'",
14324 WXS_ACTION_STR(action)((action) == 0) ? (const xmlChar *) "base" : (const xmlChar *
) "redefined"
,
14325 WXS_ITEM_TYPE_NAME(baseItem)xmlSchemaGetComponentTypeStr((xmlSchemaBasicItemPtr) (baseItem
))
,
14326 xmlSchemaGetComponentQName(&str, baseItem),
14327 NULL((void*)0));
14328 FREE_AND_NULL(str)if ((str) != ((void*)0)) { xmlFree((xmlChar *) (str)); str = (
(void*)0); }
;
14329 return(pctxt->err);
14330 }
14331 /* 4.3 Unless the {base type definition} is the `ur-type
14332 * definition`, the complex type definition's {attribute
14333 * wildcard}'s {process contents} must be identical to or
14334 * stronger than the {base type definition}'s {attribute
14335 * wildcard}'s {process contents}, where strict is stronger
14336 * than lax is stronger than skip.
14337 */
14338 if ((! WXS_IS_ANYTYPE(baseItem)(( (baseItem)->type == XML_SCHEMA_TYPE_BASIC) && (
((xmlSchemaTypePtr) (baseItem))->builtInType == XML_SCHEMAS_ANYTYPE
))
) &&
14339 (wild->processContents < baseWild->processContents)) {
14340 xmlChar *str = NULL((void*)0);
14341 xmlSchemaCustomErr4(ACTXT_CAST(xmlSchemaAbstractCtxtPtr) pctxt,
14342 XML_SCHEMAP_DERIVATION_OK_RESTRICTION_4_3,
14343 NULL((void*)0), baseItem,
14344 "The {process contents} of the attribute wildcard is "
14345 "weaker than the one in the %s %s '%s'",
14346 WXS_ACTION_STR(action)((action) == 0) ? (const xmlChar *) "base" : (const xmlChar *
) "redefined"
,
14347 WXS_ITEM_TYPE_NAME(baseItem)xmlSchemaGetComponentTypeStr((xmlSchemaBasicItemPtr) (baseItem
))
,
14348 xmlSchemaGetComponentQName(&str, baseItem),
14349 NULL((void*)0));
14350 FREE_AND_NULL(str)if ((str) != ((void*)0)) { xmlFree((xmlChar *) (str)); str = (
(void*)0); }
14351 return(pctxt->err);
14352 }
14353 }
14354 return(0);
14355}
14356
14357
14358static int
14359xmlSchemaExpandAttributeGroupRefs(xmlSchemaParserCtxtPtr pctxt,
14360 xmlSchemaBasicItemPtr item,
14361 xmlSchemaWildcardPtr *completeWild,
14362 xmlSchemaItemListPtr list,
14363 xmlSchemaItemListPtr prohibs);
14364/**
14365 * xmlSchemaFixupTypeAttributeUses:
14366 * @ctxt: the schema parser context
14367 * @type: the complex type definition
14368 *
14369 *
14370 * Builds the wildcard and the attribute uses on the given complex type.
14371 * Returns -1 if an internal error occurs, 0 otherwise.
14372 *
14373 * ATTENTION TODO: Experimentally this uses pointer comparisons for
14374 * strings, so recheck this if we start to hardcode some schemata, since
14375 * they might not be in the same dict.
14376 * NOTE: It is allowed to "extend" the xs:anyType type.
14377 */
14378static int
14379xmlSchemaFixupTypeAttributeUses(xmlSchemaParserCtxtPtr pctxt,
14380 xmlSchemaTypePtr type)
14381{
14382 xmlSchemaTypePtr baseType = NULL((void*)0);
14383 xmlSchemaAttributeUsePtr use;
14384 xmlSchemaItemListPtr uses, baseUses, prohibs = NULL((void*)0);
14385
14386 if (type->baseType == NULL((void*)0)) {
14387 PERROR_INT("xmlSchemaFixupTypeAttributeUses",xmlSchemaInternalErr((xmlSchemaAbstractCtxtPtr) pctxt, "xmlSchemaFixupTypeAttributeUses"
, "no base type");
14388 "no base type")xmlSchemaInternalErr((xmlSchemaAbstractCtxtPtr) pctxt, "xmlSchemaFixupTypeAttributeUses"
, "no base type");
;
14389 return (-1);
14390 }
14391 baseType = type->baseType;
14392 if (WXS_IS_TYPE_NOT_FIXED(baseType)(((baseType)->type != XML_SCHEMA_TYPE_BASIC) && ((
(baseType)->flags & 1 << 22) == 0))
)
14393 if (xmlSchemaTypeFixup(baseType, ACTXT_CAST(xmlSchemaAbstractCtxtPtr) pctxt) == -1)
14394 return(-1);
14395
14396 uses = type->attrUses;
14397 baseUses = baseType->attrUses;
14398 /*
14399 * Expand attribute group references. And build the 'complete'
14400 * wildcard, i.e. intersect multiple wildcards.
14401 * Move attribute prohibitions into a separate list.
14402 */
14403 if (uses != NULL((void*)0)) {
14404 if (WXS_IS_RESTRICTION(type)((type)->flags & 1 << 2)) {
14405 /*
14406 * This one will transfer all attr. prohibitions
14407 * into pctxt->attrProhibs.
14408 */
14409 if (xmlSchemaExpandAttributeGroupRefs(pctxt,
14410 WXS_BASIC_CAST(xmlSchemaBasicItemPtr) type, &(type->attributeWildcard), uses,
14411 pctxt->attrProhibs) == -1)
14412 {
14413 PERROR_INT("xmlSchemaFixupTypeAttributeUses",xmlSchemaInternalErr((xmlSchemaAbstractCtxtPtr) pctxt, "xmlSchemaFixupTypeAttributeUses"
, "failed to expand attributes");
14414 "failed to expand attributes")xmlSchemaInternalErr((xmlSchemaAbstractCtxtPtr) pctxt, "xmlSchemaFixupTypeAttributeUses"
, "failed to expand attributes");
;
14415 return(-1);
14416 }
14417 if (pctxt->attrProhibs->nbItems != 0)
14418 prohibs = pctxt->attrProhibs;
14419 } else {
14420 if (xmlSchemaExpandAttributeGroupRefs(pctxt,
14421 WXS_BASIC_CAST(xmlSchemaBasicItemPtr) type, &(type->attributeWildcard), uses,
14422 NULL((void*)0)) == -1)
14423 {
14424 PERROR_INT("xmlSchemaFixupTypeAttributeUses",xmlSchemaInternalErr((xmlSchemaAbstractCtxtPtr) pctxt, "xmlSchemaFixupTypeAttributeUses"
, "failed to expand attributes");
14425 "failed to expand attributes")xmlSchemaInternalErr((xmlSchemaAbstractCtxtPtr) pctxt, "xmlSchemaFixupTypeAttributeUses"
, "failed to expand attributes");
;
14426 return(-1);
14427 }
14428 }
14429 }
14430 /*
14431 * Inherit the attribute uses of the base type.
14432 */
14433 if (baseUses != NULL((void*)0)) {
14434 int i, j;
14435 xmlSchemaAttributeUseProhibPtr pro;
14436
14437 if (WXS_IS_RESTRICTION(type)((type)->flags & 1 << 2)) {
14438 int usesCount;
14439 xmlSchemaAttributeUsePtr tmp;
14440
14441 if (uses != NULL((void*)0))
14442 usesCount = uses->nbItems;
14443 else
14444 usesCount = 0;
14445
14446 /* Restriction. */
14447 for (i = 0; i < baseUses->nbItems; i++) {
14448 use = baseUses->items[i];
14449 if (prohibs) {
14450 /*
14451 * Filter out prohibited uses.
14452 */
14453 for (j = 0; j < prohibs->nbItems; j++) {
14454 pro = prohibs->items[j];
14455 if ((WXS_ATTRUSE_DECL_NAME(use)(((xmlSchemaAttributeUsePtr) (use))->attrDecl)->name == pro->name) &&
14456 (WXS_ATTRUSE_DECL_TNS(use)(((xmlSchemaAttributeUsePtr) (use))->attrDecl)->targetNamespace ==
14457 pro->targetNamespace))
14458 {
14459 goto inherit_next;
14460 }
14461 }
14462 }
14463 if (usesCount) {
14464 /*
14465 * Filter out existing uses.
14466 */
14467 for (j = 0; j < usesCount; j++) {
14468 tmp = uses->items[j];
14469 if ((WXS_ATTRUSE_DECL_NAME(use)(((xmlSchemaAttributeUsePtr) (use))->attrDecl)->name ==
14470 WXS_ATTRUSE_DECL_NAME(tmp)(((xmlSchemaAttributeUsePtr) (tmp))->attrDecl)->name) &&
14471 (WXS_ATTRUSE_DECL_TNS(use)(((xmlSchemaAttributeUsePtr) (use))->attrDecl)->targetNamespace ==
14472 WXS_ATTRUSE_DECL_TNS(tmp)(((xmlSchemaAttributeUsePtr) (tmp))->attrDecl)->targetNamespace))
14473 {
14474 goto inherit_next;
14475 }
14476 }
14477 }
14478 if (uses == NULL((void*)0)) {
14479 type->attrUses = xmlSchemaItemListCreate();
14480 if (type->attrUses == NULL((void*)0))
14481 goto exit_failure;
14482 uses = type->attrUses;
14483 }
14484 xmlSchemaItemListAddSize(uses, 2, use);
14485inherit_next: {}
14486 }
14487 } else {
14488 /* Extension. */
14489 for (i = 0; i < baseUses->nbItems; i++) {
14490 use = baseUses->items[i];
14491 if (uses == NULL((void*)0)) {
14492 type->attrUses = xmlSchemaItemListCreate();
14493 if (type->attrUses == NULL((void*)0))
14494 goto exit_failure;
14495 uses = type->attrUses;
14496 }
14497 xmlSchemaItemListAddSize(uses, baseUses->nbItems, use);
14498 }
14499 }
14500 }
14501 /*
14502 * Shrink attr. uses.
14503 */
14504 if (uses) {
14505 if (uses->nbItems == 0) {
14506 xmlSchemaItemListFree(uses);
14507 type->attrUses = NULL((void*)0);
14508 }
14509 /*
14510 * TODO: We could shrink the size of the array
14511 * to fit the actual number of items.
14512 */
14513 }
14514 /*
14515 * Compute the complete wildcard.
14516 */
14517 if (WXS_IS_EXTENSION(type)((type)->flags & 1 << 1)) {
14518 if (baseType->attributeWildcard != NULL((void*)0)) {
14519 /*
14520 * (3.2.2.1) "If the `base wildcard` is non-`absent`, then
14521 * the appropriate case among the following:"
14522 */
14523 if (type->attributeWildcard != NULL((void*)0)) {
14524 /*
14525 * Union the complete wildcard with the base wildcard.
14526 * SPEC {attribute wildcard}
14527 * (3.2.2.1.2) "otherwise a wildcard whose {process contents}
14528 * and {annotation} are those of the `complete wildcard`,
14529 * and whose {namespace constraint} is the intensional union
14530 * of the {namespace constraint} of the `complete wildcard`
14531 * and of the `base wildcard`, as defined in Attribute
14532 * Wildcard Union ($3.10.6)."
14533 */
14534 if (xmlSchemaUnionWildcards(pctxt, type->attributeWildcard,
14535 baseType->attributeWildcard) == -1)
14536 goto exit_failure;
14537 } else {
14538 /*
14539 * (3.2.2.1.1) "If the `complete wildcard` is `absent`,
14540 * then the `base wildcard`."
14541 */
14542 type->attributeWildcard = baseType->attributeWildcard;
14543 }
14544 } else {
14545 /*
14546 * (3.2.2.2) "otherwise (the `base wildcard` is `absent`) the
14547 * `complete wildcard`"
14548 * NOOP
14549 */
14550 }
14551 } else {
14552 /*
14553 * SPEC {attribute wildcard}
14554 * (3.1) "If the <restriction> alternative is chosen, then the
14555 * `complete wildcard`;"
14556 * NOOP
14557 */
14558 }
14559
14560 return (0);
14561
14562exit_failure:
14563 return(-1);
14564}
14565
14566/**
14567 * xmlSchemaTypeFinalContains:
14568 * @schema: the schema
14569 * @type: the type definition
14570 * @final: the final
14571 *
14572 * Evaluates if a type definition contains the given "final".
14573 * This does take "finalDefault" into account as well.
14574 *
14575 * Returns 1 if the type does contain the given "final",
14576 * 0 otherwise.
14577 */
14578static int
14579xmlSchemaTypeFinalContains(xmlSchemaTypePtr type, int final)
14580{
14581 if (type == NULL((void*)0))
14582 return (0);
14583 if (type->flags & final)
14584 return (1);
14585 else
14586 return (0);
14587}
14588
14589/**
14590 * xmlSchemaGetUnionSimpleTypeMemberTypes:
14591 * @type: the Union Simple Type
14592 *
14593 * Returns a list of member types of @type if existing,
14594 * returns NULL otherwise.
14595 */
14596static xmlSchemaTypeLinkPtr
14597xmlSchemaGetUnionSimpleTypeMemberTypes(xmlSchemaTypePtr type)
14598{
14599 while ((type != NULL((void*)0)) && (type->type == XML_SCHEMA_TYPE_SIMPLE)) {
14600 if (type->memberTypes != NULL((void*)0))
14601 return (type->memberTypes);
14602 else
14603 type = type->baseType;
14604 }
14605 return (NULL((void*)0));
14606}
14607
14608#if 0
14609/**
14610 * xmlSchemaGetParticleTotalRangeMin:
14611 * @particle: the particle
14612 *
14613 * Schema Component Constraint: Effective Total Range
14614 * (all and sequence) + (choice)
14615 *
14616 * Returns the minimum Effective Total Range.
14617 */
14618static int
14619xmlSchemaGetParticleTotalRangeMin(xmlSchemaParticlePtr particle)
14620{
14621 if ((particle->children == NULL((void*)0)) ||
14622 (particle->minOccurs == 0))
14623 return (0);
14624 if (particle->children->type == XML_SCHEMA_TYPE_CHOICE) {
14625 int min = -1, cur;
14626 xmlSchemaParticlePtr part =
14627 (xmlSchemaParticlePtr) particle->children->children;
14628
14629 if (part == NULL((void*)0))
14630 return (0);
14631 while (part != NULL((void*)0)) {
14632 if ((part->children->type == XML_SCHEMA_TYPE_ELEMENT) ||
14633 (part->children->type == XML_SCHEMA_TYPE_ANY))
14634 cur = part->minOccurs;
14635 else
14636 cur = xmlSchemaGetParticleTotalRangeMin(part);
14637 if (cur == 0)
14638 return (0);
14639 if ((min > cur) || (min == -1))
14640 min = cur;
14641 part = (xmlSchemaParticlePtr) part->next;
14642 }
14643 return (particle->minOccurs * min);
14644 } else {
14645 /* <all> and <sequence> */
14646 int sum = 0;
14647 xmlSchemaParticlePtr part =
14648 (xmlSchemaParticlePtr) particle->children->children;
14649
14650 if (part == NULL((void*)0))
14651 return (0);
14652 do {
14653 if ((part->children->type == XML_SCHEMA_TYPE_ELEMENT) ||
14654 (part->children->type == XML_SCHEMA_TYPE_ANY))
14655 sum += part->minOccurs;
14656 else
14657 sum += xmlSchemaGetParticleTotalRangeMin(part);
14658 part = (xmlSchemaParticlePtr) part->next;
14659 } while (part != NULL((void*)0));
14660 return (particle->minOccurs * sum);
14661 }
14662}
14663
14664/**
14665 * xmlSchemaGetParticleTotalRangeMax:
14666 * @particle: the particle
14667 *
14668 * Schema Component Constraint: Effective Total Range
14669 * (all and sequence) + (choice)
14670 *
14671 * Returns the maximum Effective Total Range.
14672 */
14673static int
14674xmlSchemaGetParticleTotalRangeMax(xmlSchemaParticlePtr particle)
14675{
14676 if ((particle->children == NULL((void*)0)) ||
14677 (particle->children->children == NULL((void*)0)))
14678 return (0);
14679 if (particle->children->type == XML_SCHEMA_TYPE_CHOICE) {
14680 int max = -1, cur;
14681 xmlSchemaParticlePtr part =
14682 (xmlSchemaParticlePtr) particle->children->children;
14683
14684 for (; part != NULL((void*)0); part = (xmlSchemaParticlePtr) part->next) {
14685 if (part->children == NULL((void*)0))
14686 continue;
14687 if ((part->children->type == XML_SCHEMA_TYPE_ELEMENT) ||
14688 (part->children->type == XML_SCHEMA_TYPE_ANY))
14689 cur = part->maxOccurs;
14690 else
14691 cur = xmlSchemaGetParticleTotalRangeMax(part);
14692 if (cur == UNBOUNDED(1 << 30))
14693 return (UNBOUNDED(1 << 30));
14694 if ((max < cur) || (max == -1))
14695 max = cur;
14696 }
14697 /* TODO: Handle overflows? */
14698 return (particle->maxOccurs * max);
14699 } else {
14700 /* <all> and <sequence> */
14701 int sum = 0, cur;
14702 xmlSchemaParticlePtr part =
14703 (xmlSchemaParticlePtr) particle->children->children;
14704
14705 for (; part != NULL((void*)0); part = (xmlSchemaParticlePtr) part->next) {
14706 if (part->children == NULL((void*)0))
14707 continue;
14708 if ((part->children->type == XML_SCHEMA_TYPE_ELEMENT) ||
14709 (part->children->type == XML_SCHEMA_TYPE_ANY))
14710 cur = part->maxOccurs;
14711 else
14712 cur = xmlSchemaGetParticleTotalRangeMax(part);
14713 if (cur == UNBOUNDED(1 << 30))
14714 return (UNBOUNDED(1 << 30));
14715 if ((cur > 0) && (particle->maxOccurs == UNBOUNDED(1 << 30)))
14716 return (UNBOUNDED(1 << 30));
14717 sum += cur;
14718 }
14719 /* TODO: Handle overflows? */
14720 return (particle->maxOccurs * sum);
14721 }
14722}
14723#endif
14724
14725/**
14726 * xmlSchemaGetParticleEmptiable:
14727 * @particle: the particle
14728 *
14729 * Returns 1 if emptiable, 0 otherwise.
14730 */
14731static int
14732xmlSchemaGetParticleEmptiable(xmlSchemaParticlePtr particle)
14733{
14734 xmlSchemaParticlePtr part;
14735 int emptiable;
14736
14737 if ((particle->children == NULL((void*)0)) || (particle->minOccurs == 0))
14738 return (1);
14739
14740 part = (xmlSchemaParticlePtr) particle->children->children;
14741 if (part == NULL((void*)0))
14742 return (1);
14743
14744 while (part != NULL((void*)0)) {
14745 if ((part->children->type == XML_SCHEMA_TYPE_ELEMENT) ||
14746 (part->children->type == XML_SCHEMA_TYPE_ANY))
14747 emptiable = (part->minOccurs == 0);
14748 else
14749 emptiable = xmlSchemaGetParticleEmptiable(part);
14750 if (particle->children->type == XML_SCHEMA_TYPE_CHOICE) {
14751 if (emptiable)
14752 return (1);
14753 } else {
14754 /* <all> and <sequence> */
14755 if (!emptiable)
14756 return (0);
14757 }
14758 part = (xmlSchemaParticlePtr) part->next;
14759 }
14760
14761 if (particle->children->type == XML_SCHEMA_TYPE_CHOICE)
14762 return (0);
14763 else
14764 return (1);
14765}
14766
14767/**
14768 * xmlSchemaIsParticleEmptiable:
14769 * @particle: the particle
14770 *
14771 * Schema Component Constraint: Particle Emptiable
14772 * Checks whether the given particle is emptiable.
14773 *
14774 * Returns 1 if emptiable, 0 otherwise.
14775 */
14776static int
14777xmlSchemaIsParticleEmptiable(xmlSchemaParticlePtr particle)
14778{
14779 /*
14780 * SPEC (1) "Its {min occurs} is 0."
14781 */
14782 if ((particle == NULL((void*)0)) || (particle->minOccurs == 0) ||
14783 (particle->children == NULL((void*)0)))
14784 return (1);
14785 /*
14786 * SPEC (2) "Its {term} is a group and the minimum part of the
14787 * effective total range of that group, [...] is 0."
14788 */
14789 if (WXS_IS_MODEL_GROUP(particle->children)(((particle->children)->type == XML_SCHEMA_TYPE_SEQUENCE
) || ((particle->children)->type == XML_SCHEMA_TYPE_CHOICE
) || ((particle->children)->type == XML_SCHEMA_TYPE_ALL
))
)
14790 return (xmlSchemaGetParticleEmptiable(particle));
14791 return (0);
14792}
14793
14794/**
14795 * xmlSchemaCheckCOSSTDerivedOK:
14796 * @actxt: a context
14797 * @type: the derived simple type definition
14798 * @baseType: the base type definition
14799 * @subset: the subset of ('restriction', etc.)
14800 *
14801 * Schema Component Constraint:
14802 * Type Derivation OK (Simple) (cos-st-derived-OK)
14803 *
14804 * Checks whether @type can be validly
14805 * derived from @baseType.
14806 *
14807 * Returns 0 on success, an positive error code otherwise.
14808 */
14809static int
14810xmlSchemaCheckCOSSTDerivedOK(xmlSchemaAbstractCtxtPtr actxt,
14811 xmlSchemaTypePtr type,
14812 xmlSchemaTypePtr baseType,
14813 int subset)
14814{
14815 /*
14816 * 1 They are the same type definition.
14817 * TODO: The identity check might have to be more complex than this.
14818 */
14819 if (type == baseType)
14820 return (0);
14821 /*
14822 * 2.1 restriction is not in the subset, or in the {final}
14823 * of its own {base type definition};
14824 *
14825 * NOTE that this will be used also via "xsi:type".
14826 *
14827 * TODO: Revise this, it looks strange. How can the "type"
14828 * not be fixed or *in* fixing?
14829 */
14830 if (WXS_IS_TYPE_NOT_FIXED(type)(((type)->type != XML_SCHEMA_TYPE_BASIC) && (((type
)->flags & 1 << 22) == 0))
)
14831 if (xmlSchemaTypeFixup(type, actxt) == -1)
14832 return(-1);
14833 if (WXS_IS_TYPE_NOT_FIXED(baseType)(((baseType)->type != XML_SCHEMA_TYPE_BASIC) && ((
(baseType)->flags & 1 << 22) == 0))
)
14834 if (xmlSchemaTypeFixup(baseType, actxt) == -1)
14835 return(-1);
14836 if ((subset & SUBSET_RESTRICTION1<<0) ||
14837 (xmlSchemaTypeFinalContains(type->baseType,
14838 XML_SCHEMAS_TYPE_FINAL_RESTRICTION1 << 10))) {
14839 return (XML_SCHEMAP_COS_ST_DERIVED_OK_2_1);
14840 }
14841 /* 2.2 */
14842 if (type->baseType == baseType) {
14843 /*
14844 * 2.2.1 D's `base type definition` is B.
14845 */
14846 return (0);
14847 }
14848 /*
14849 * 2.2.2 D's `base type definition` is not the `ur-type definition`
14850 * and is validly derived from B given the subset, as defined by this
14851 * constraint.
14852 */
14853 if ((! WXS_IS_ANYTYPE(type->baseType)(( (type->baseType)->type == XML_SCHEMA_TYPE_BASIC) &&
( ((xmlSchemaTypePtr) (type->baseType))->builtInType ==
XML_SCHEMAS_ANYTYPE))
) &&
14854 (xmlSchemaCheckCOSSTDerivedOK(actxt, type->baseType,
14855 baseType, subset) == 0)) {
14856 return (0);
14857 }
14858 /*
14859 * 2.2.3 D's {variety} is list or union and B is the `simple ur-type
14860 * definition`.
14861 */
14862 if (WXS_IS_ANY_SIMPLE_TYPE(baseType)(((baseType)->type == XML_SCHEMA_TYPE_BASIC) && ((
baseType)->builtInType == XML_SCHEMAS_ANYSIMPLETYPE))
&&
14863 (WXS_IS_LIST(type)(type->flags & 1 << 6) || WXS_IS_UNION(type)(type->flags & 1 << 7))) {
14864 return (0);
14865 }
14866 /*
14867 * 2.2.4 B's {variety} is union and D is validly derived from a type
14868 * definition in B's {member type definitions} given the subset, as
14869 * defined by this constraint.
14870 *
14871 * NOTE: This seems not to involve built-in types, since there is no
14872 * built-in Union Simple Type.
14873 */
14874 if (WXS_IS_UNION(baseType)(baseType->flags & 1 << 7)) {
14875 xmlSchemaTypeLinkPtr cur;
14876
14877 cur = baseType->memberTypes;
14878 while (cur != NULL((void*)0)) {
14879 if (WXS_IS_TYPE_NOT_FIXED(cur->type)(((cur->type)->type != XML_SCHEMA_TYPE_BASIC) &&
(((cur->type)->flags & 1 << 22) == 0))
)
14880 if (xmlSchemaTypeFixup(cur->type, actxt) == -1)
14881 return(-1);
14882 if (xmlSchemaCheckCOSSTDerivedOK(actxt,
14883 type, cur->type, subset) == 0)
14884 {
14885 /*
14886 * It just has to be validly derived from at least one
14887 * member-type.
14888 */
14889 return (0);
14890 }
14891 cur = cur->next;
14892 }
14893 }
14894 return (XML_SCHEMAP_COS_ST_DERIVED_OK_2_2);
14895}
14896
14897/**
14898 * xmlSchemaCheckTypeDefCircularInternal:
14899 * @pctxt: the schema parser context
14900 * @ctxtType: the type definition
14901 * @ancestor: an ancestor of @ctxtType
14902 *
14903 * Checks st-props-correct (2) + ct-props-correct (3).
14904 * Circular type definitions are not allowed.
14905 *
14906 * Returns XML_SCHEMAP_ST_PROPS_CORRECT_2 if the given type is
14907 * circular, 0 otherwise.
14908 */
14909static int
14910xmlSchemaCheckTypeDefCircularInternal(xmlSchemaParserCtxtPtr pctxt,
14911 xmlSchemaTypePtr ctxtType,
14912 xmlSchemaTypePtr ancestor)
14913{
14914 int ret;
14915
14916 if ((ancestor == NULL((void*)0)) || (ancestor->type == XML_SCHEMA_TYPE_BASIC))
14917 return (0);
14918
14919 if (ctxtType == ancestor) {
14920 xmlSchemaPCustomErr(pctxt,
14921 XML_SCHEMAP_ST_PROPS_CORRECT_2,
14922 WXS_BASIC_CAST(xmlSchemaBasicItemPtr) ctxtType, WXS_ITEM_NODE(ctxtType)xmlSchemaGetComponentNode((xmlSchemaBasicItemPtr) (ctxtType)),
14923 "The definition is circular", NULL((void*)0));
14924 return (XML_SCHEMAP_ST_PROPS_CORRECT_2);
14925 }
14926 if (ancestor->flags & XML_SCHEMAS_TYPE_MARKED1 << 16) {
14927 /*
14928 * Avoid infinite recursion on circular types not yet checked.
14929 */
14930 return (0);
14931 }
14932 ancestor->flags |= XML_SCHEMAS_TYPE_MARKED1 << 16;
14933 ret = xmlSchemaCheckTypeDefCircularInternal(pctxt, ctxtType,
14934 ancestor->baseType);
14935 ancestor->flags ^= XML_SCHEMAS_TYPE_MARKED1 << 16;
14936 return (ret);
14937}
14938
14939/**
14940 * xmlSchemaCheckTypeDefCircular:
14941 * @item: the complex/simple type definition
14942 * @ctxt: the parser context
14943 * @name: the name
14944 *
14945 * Checks for circular type definitions.
14946 */
14947static void
14948xmlSchemaCheckTypeDefCircular(xmlSchemaTypePtr item,
14949 xmlSchemaParserCtxtPtr ctxt)
14950{
14951 if ((item == NULL((void*)0)) ||
14952 (item->type == XML_SCHEMA_TYPE_BASIC) ||
14953 (item->baseType == NULL((void*)0)))
14954 return;
14955 xmlSchemaCheckTypeDefCircularInternal(ctxt, item,
14956 item->baseType);
14957}
14958
14959/*
14960* Simple Type Definition Representation OK (src-simple-type) 4
14961*
14962* "4 Circular union type definition is disallowed. That is, if the
14963* <union> alternative is chosen, there must not be any entries in the
14964* memberTypes [attribute] at any depth which resolve to the component
14965* corresponding to the <simpleType>."
14966*
14967* Note that this should work on the *representation* of a component,
14968* thus assumes any union types in the member types not being yet
14969* substituted. At this stage we need the variety of the types
14970* to be already computed.
14971*/
14972static int
14973xmlSchemaCheckUnionTypeDefCircularRecur(xmlSchemaParserCtxtPtr pctxt,
14974 xmlSchemaTypePtr ctxType,
14975 xmlSchemaTypeLinkPtr members)
14976{
14977 xmlSchemaTypeLinkPtr member;
14978 xmlSchemaTypePtr memberType;
14979
14980 member = members;
14981 while (member != NULL((void*)0)) {
14982 memberType = member->type;
14983 while ((memberType != NULL((void*)0)) &&
14984 (memberType->type != XML_SCHEMA_TYPE_BASIC)) {
14985 if (memberType == ctxType) {
14986 xmlSchemaPCustomErr(pctxt,
14987 XML_SCHEMAP_SRC_SIMPLE_TYPE_4,
14988 WXS_BASIC_CAST(xmlSchemaBasicItemPtr) ctxType, NULL((void*)0),
14989 "The union type definition is circular", NULL((void*)0));
14990 return (XML_SCHEMAP_SRC_SIMPLE_TYPE_4);
14991 }
14992 if ((WXS_IS_UNION(memberType)(memberType->flags & 1 << 7)) &&
14993 ((memberType->flags & XML_SCHEMAS_TYPE_MARKED1 << 16) == 0))
14994 {
14995 int res;
14996 memberType->flags |= XML_SCHEMAS_TYPE_MARKED1 << 16;
14997 res = xmlSchemaCheckUnionTypeDefCircularRecur(pctxt,
14998 ctxType,
14999 xmlSchemaGetUnionSimpleTypeMemberTypes(memberType));
15000 memberType->flags ^= XML_SCHEMAS_TYPE_MARKED1 << 16;
15001 if (res != 0)
15002 return(res);
15003 }
15004 memberType = memberType->baseType;
15005 }
15006 member = member->next;
15007 }
15008 return(0);
15009}
15010
15011static int
15012xmlSchemaCheckUnionTypeDefCircular(xmlSchemaParserCtxtPtr pctxt,
15013 xmlSchemaTypePtr type)
15014{
15015 if (! WXS_IS_UNION(type)(type->flags & 1 << 7))
15016 return(0);
15017 return(xmlSchemaCheckUnionTypeDefCircularRecur(pctxt, type,
15018 type->memberTypes));
15019}
15020
15021/**
15022 * xmlSchemaResolveTypeReferences:
15023 * @item: the complex/simple type definition
15024 * @ctxt: the parser context
15025 * @name: the name
15026 *
15027 * Resolves type definition references
15028 */
15029static void
15030xmlSchemaResolveTypeReferences(xmlSchemaTypePtr typeDef,
15031 xmlSchemaParserCtxtPtr ctxt)
15032{
15033 if (typeDef == NULL((void*)0))
15034 return;
15035
15036 /*
15037 * Resolve the base type.
15038 */
15039 if (typeDef->baseType == NULL((void*)0)) {
15040 typeDef->baseType = xmlSchemaGetType(ctxt->schema,
15041 typeDef->base, typeDef->baseNs);
15042 if (typeDef->baseType == NULL((void*)0)) {
15043 xmlSchemaPResCompAttrErr(ctxt,
15044 XML_SCHEMAP_SRC_RESOLVE,
15045 WXS_BASIC_CAST(xmlSchemaBasicItemPtr) typeDef, typeDef->node,
15046 "base", typeDef->base, typeDef->baseNs,
15047 XML_SCHEMA_TYPE_SIMPLE, NULL((void*)0));
15048 return;
15049 }
15050 }
15051 if (WXS_IS_SIMPLE(typeDef)((typeDef->type == XML_SCHEMA_TYPE_SIMPLE) || ((typeDef->
type == XML_SCHEMA_TYPE_BASIC) && (typeDef->builtInType
!= XML_SCHEMAS_ANYTYPE)))
) {
15052 if (WXS_IS_UNION(typeDef)(typeDef->flags & 1 << 7)) {
15053 /*
15054 * Resolve the memberTypes.
15055 */
15056 xmlSchemaResolveUnionMemberTypes(ctxt, typeDef);
15057 return;
15058 } else if (WXS_IS_LIST(typeDef)(typeDef->flags & 1 << 6)) {
15059 /*
15060 * Resolve the itemType.
15061 */
15062 if ((typeDef->subtypes == NULL((void*)0)) && (typeDef->base != NULL((void*)0))) {
15063
15064 typeDef->subtypes = xmlSchemaGetType(ctxt->schema,
15065 typeDef->base, typeDef->baseNs);
15066
15067 if ((typeDef->subtypes == NULL((void*)0)) ||
15068 (! WXS_IS_SIMPLE(typeDef->subtypes)((typeDef->subtypes->type == XML_SCHEMA_TYPE_SIMPLE) ||
((typeDef->subtypes->type == XML_SCHEMA_TYPE_BASIC) &&
(typeDef->subtypes->builtInType != XML_SCHEMAS_ANYTYPE
)))
))
15069 {
15070 typeDef->subtypes = NULL((void*)0);
15071 xmlSchemaPResCompAttrErr(ctxt,
15072 XML_SCHEMAP_SRC_RESOLVE,
15073 WXS_BASIC_CAST(xmlSchemaBasicItemPtr) typeDef, typeDef->node,
15074 "itemType", typeDef->base, typeDef->baseNs,
15075 XML_SCHEMA_TYPE_SIMPLE, NULL((void*)0));
15076 }
15077 }
15078 return;
15079 }
15080 }
15081 /*
15082 * The ball of letters below means, that if we have a particle
15083 * which has a QName-helper component as its {term}, we want
15084 * to resolve it...
15085 */
15086 else if ((WXS_TYPE_CONTENTTYPE(typeDef)(typeDef)->subtypes != NULL((void*)0)) &&
15087 ((WXS_TYPE_CONTENTTYPE(typeDef)(typeDef)->subtypes)->type ==
15088 XML_SCHEMA_TYPE_PARTICLE) &&
15089 (WXS_TYPE_PARTICLE_TERM(typeDef)((xmlSchemaParticlePtr) ((xmlSchemaParticlePtr) (typeDef)->
subtypes))->children
!= NULL((void*)0)) &&
15090 ((WXS_TYPE_PARTICLE_TERM(typeDef)((xmlSchemaParticlePtr) ((xmlSchemaParticlePtr) (typeDef)->
subtypes))->children
)->type ==
15091 XML_SCHEMA_EXTRA_QNAMEREF))
15092 {
15093 xmlSchemaQNameRefPtr ref =
15094 WXS_QNAME_CAST(xmlSchemaQNameRefPtr) WXS_TYPE_PARTICLE_TERM(typeDef)((xmlSchemaParticlePtr) ((xmlSchemaParticlePtr) (typeDef)->
subtypes))->children
;
15095 xmlSchemaModelGroupDefPtr groupDef;
15096
15097 /*
15098 * URGENT TODO: Test this.
15099 */
15100 WXS_TYPE_PARTICLE_TERM(typeDef)((xmlSchemaParticlePtr) ((xmlSchemaParticlePtr) (typeDef)->
subtypes))->children
= NULL((void*)0);
15101 /*
15102 * Resolve the MG definition reference.
15103 */
15104 groupDef =
15105 WXS_MODEL_GROUPDEF_CAST(xmlSchemaModelGroupDefPtr) xmlSchemaGetNamedComponent(ctxt->schema,
15106 ref->itemType, ref->name, ref->targetNamespace);
15107 if (groupDef == NULL((void*)0)) {
15108 xmlSchemaPResCompAttrErr(ctxt, XML_SCHEMAP_SRC_RESOLVE,
15109 NULL((void*)0), WXS_ITEM_NODE(WXS_TYPE_PARTICLE(typeDef))xmlSchemaGetComponentNode((xmlSchemaBasicItemPtr) ((xmlSchemaParticlePtr
) (typeDef)->subtypes))
,
15110 "ref", ref->name, ref->targetNamespace, ref->itemType,
15111 NULL((void*)0));
15112 /* Remove the particle. */
15113 WXS_TYPE_CONTENTTYPE(typeDef)(typeDef)->subtypes = NULL((void*)0);
15114 } else if (WXS_MODELGROUPDEF_MODEL(groupDef)((xmlSchemaModelGroupPtr) (groupDef))->children == NULL((void*)0))
15115 /* Remove the particle. */
15116 WXS_TYPE_CONTENTTYPE(typeDef)(typeDef)->subtypes = NULL((void*)0);
15117 else {
15118 /*
15119 * Assign the MG definition's {model group} to the
15120 * particle's {term}.
15121 */
15122 WXS_TYPE_PARTICLE_TERM(typeDef)((xmlSchemaParticlePtr) ((xmlSchemaParticlePtr) (typeDef)->
subtypes))->children
= WXS_MODELGROUPDEF_MODEL(groupDef)((xmlSchemaModelGroupPtr) (groupDef))->children;
15123
15124 if (WXS_MODELGROUPDEF_MODEL(groupDef)((xmlSchemaModelGroupPtr) (groupDef))->children->type == XML_SCHEMA_TYPE_ALL) {
15125 /*
15126 * SPEC cos-all-limited (1.2)
15127 * "1.2 the {term} property of a particle with
15128 * {max occurs}=1 which is part of a pair which constitutes
15129 * the {content type} of a complex type definition."
15130 */
15131 if ((WXS_TYPE_PARTICLE(typeDef)(xmlSchemaParticlePtr) (typeDef)->subtypes)->maxOccurs != 1) {
15132 xmlSchemaCustomErr(ACTXT_CAST(xmlSchemaAbstractCtxtPtr) ctxt,
15133 /* TODO: error code */
15134 XML_SCHEMAP_COS_ALL_LIMITED,
15135 WXS_ITEM_NODE(WXS_TYPE_PARTICLE(typeDef))xmlSchemaGetComponentNode((xmlSchemaBasicItemPtr) ((xmlSchemaParticlePtr
) (typeDef)->subtypes))
, NULL((void*)0),
15136 "The particle's {max occurs} must be 1, since the "
15137 "reference resolves to an 'all' model group",
15138 NULL((void*)0), NULL((void*)0));
15139 }
15140 }
15141 }
15142 }
15143}
15144
15145
15146
15147/**
15148 * xmlSchemaCheckSTPropsCorrect:
15149 * @ctxt: the schema parser context
15150 * @type: the simple type definition
15151 *
15152 * Checks st-props-correct.
15153 *
15154 * Returns 0 if the properties are correct,
15155 * if not, a positive error code and -1 on internal
15156 * errors.
15157 */
15158static int
15159xmlSchemaCheckSTPropsCorrect(xmlSchemaParserCtxtPtr ctxt,
15160 xmlSchemaTypePtr type)
15161{
15162 xmlSchemaTypePtr baseType = type->baseType;
15163 xmlChar *str = NULL((void*)0);
15164
15165 /* STATE: error funcs converted. */
15166 /*
15167 * Schema Component Constraint: Simple Type Definition Properties Correct
15168 *
15169 * NOTE: This is somehow redundant, since we actually built a simple type
15170 * to have all the needed information; this acts as an self test.
15171 */
15172 /* Base type: If the datatype has been `derived` by `restriction`
15173 * then the Simple Type Definition component from which it is `derived`,
15174 * otherwise the Simple Type Definition for anySimpleType ($4.1.6).
15175 */
15176 if (baseType == NULL((void*)0)) {
15177 /*
15178 * TODO: Think about: "modulo the impact of Missing
15179 * Sub-components ($5.3)."
15180 */
15181 xmlSchemaPCustomErr(ctxt,
15182 XML_SCHEMAP_ST_PROPS_CORRECT_1,
15183 WXS_BASIC_CAST(xmlSchemaBasicItemPtr) type, NULL((void*)0),
15184 "No base type existent", NULL((void*)0));
15185 return (XML_SCHEMAP_ST_PROPS_CORRECT_1);
15186
15187 }
15188 if (! WXS_IS_SIMPLE(baseType)((baseType->type == XML_SCHEMA_TYPE_SIMPLE) || ((baseType->
type == XML_SCHEMA_TYPE_BASIC) && (baseType->builtInType
!= XML_SCHEMAS_ANYTYPE)))
) {
15189 xmlSchemaPCustomErr(ctxt,
15190 XML_SCHEMAP_ST_PROPS_CORRECT_1,
15191 WXS_BASIC_CAST(xmlSchemaBasicItemPtr) type, NULL((void*)0),
15192 "The base type '%s' is not a simple type",
15193 xmlSchemaGetComponentQName(&str, baseType));
15194 FREE_AND_NULL(str)if ((str) != ((void*)0)) { xmlFree((xmlChar *) (str)); str = (
(void*)0); }
15195 return (XML_SCHEMAP_ST_PROPS_CORRECT_1);
15196 }
15197 if ((WXS_IS_LIST(type)(type->flags & 1 << 6) || WXS_IS_UNION(type)(type->flags & 1 << 7)) &&
15198 (WXS_IS_RESTRICTION(type)((type)->flags & 1 << 2) == 0) &&
15199 ((! WXS_IS_ANY_SIMPLE_TYPE(baseType)(((baseType)->type == XML_SCHEMA_TYPE_BASIC) && ((
baseType)->builtInType == XML_SCHEMAS_ANYSIMPLETYPE))
) &&
15200 (baseType->type != XML_SCHEMA_TYPE_SIMPLE))) {
15201 xmlSchemaPCustomErr(ctxt,
15202 XML_SCHEMAP_ST_PROPS_CORRECT_1,
15203 WXS_BASIC_CAST(xmlSchemaBasicItemPtr) type, NULL((void*)0),
15204 "A type, derived by list or union, must have "
15205 "the simple ur-type definition as base type, not '%s'",
15206 xmlSchemaGetComponentQName(&str, baseType));
15207 FREE_AND_NULL(str)if ((str) != ((void*)0)) { xmlFree((xmlChar *) (str)); str = (
(void*)0); }
15208 return (XML_SCHEMAP_ST_PROPS_CORRECT_1);
15209 }
15210 /*
15211 * Variety: One of {atomic, list, union}.
15212 */
15213 if ((! WXS_IS_ATOMIC(type)(type->flags & 1 << 8)) && (! WXS_IS_UNION(type)(type->flags & 1 << 7)) &&
15214 (! WXS_IS_LIST(type)(type->flags & 1 << 6))) {
15215 xmlSchemaPCustomErr(ctxt,
15216 XML_SCHEMAP_ST_PROPS_CORRECT_1,
15217 WXS_BASIC_CAST(xmlSchemaBasicItemPtr) type, NULL((void*)0),
15218 "The variety is absent", NULL((void*)0));
15219 return (XML_SCHEMAP_ST_PROPS_CORRECT_1);
15220 }
15221 /* TODO: Finish this. Hmm, is this finished? */
15222
15223 /*
15224 * 3 The {final} of the {base type definition} must not contain restriction.
15225 */
15226 if (xmlSchemaTypeFinalContains(baseType,
15227 XML_SCHEMAS_TYPE_FINAL_RESTRICTION1 << 10)) {
15228 xmlSchemaPCustomErr(ctxt,
15229 XML_SCHEMAP_ST_PROPS_CORRECT_3,
15230 WXS_BASIC_CAST(xmlSchemaBasicItemPtr) type, NULL((void*)0),
15231 "The 'final' of its base type '%s' must not contain "
15232 "'restriction'",
15233 xmlSchemaGetComponentQName(&str, baseType));
15234 FREE_AND_NULL(str)if ((str) != ((void*)0)) { xmlFree((xmlChar *) (str)); str = (
(void*)0); }
15235 return (XML_SCHEMAP_ST_PROPS_CORRECT_3);
15236 }
15237
15238 /*
15239 * 2 All simple type definitions must be derived ultimately from the `simple
15240 * ur-type definition` (so circular definitions are disallowed). That is, it
15241 * must be possible to reach a built-in primitive datatype or the `simple
15242 * ur-type definition` by repeatedly following the {base type definition}.
15243 *
15244 * NOTE: this is done in xmlSchemaCheckTypeDefCircular().
15245 */
15246 return (0);
15247}
15248
15249/**
15250 * xmlSchemaCheckCOSSTRestricts:
15251 * @ctxt: the schema parser context
15252 * @type: the simple type definition
15253 *
15254 * Schema Component Constraint:
15255 * Derivation Valid (Restriction, Simple) (cos-st-restricts)
15256
15257 * Checks if the given @type (simpleType) is derived validly by restriction.
15258 * STATUS:
15259 *
15260 * Returns -1 on internal errors, 0 if the type is validly derived,
15261 * a positive error code otherwise.
15262 */
15263static int
15264xmlSchemaCheckCOSSTRestricts(xmlSchemaParserCtxtPtr pctxt,
15265 xmlSchemaTypePtr type)
15266{
15267 xmlChar *str = NULL((void*)0);
15268
15269 if (type->type != XML_SCHEMA_TYPE_SIMPLE) {
15270 PERROR_INT("xmlSchemaCheckCOSSTRestricts",xmlSchemaInternalErr((xmlSchemaAbstractCtxtPtr) pctxt, "xmlSchemaCheckCOSSTRestricts"
, "given type is not a user-derived simpleType");
15271 "given type is not a user-derived simpleType")xmlSchemaInternalErr((xmlSchemaAbstractCtxtPtr) pctxt, "xmlSchemaCheckCOSSTRestricts"
, "given type is not a user-derived simpleType");
;
15272 return (-1);
15273 }
15274
15275 if (WXS_IS_ATOMIC(type)(type->flags & 1 << 8)) {
15276 xmlSchemaTypePtr primitive;
15277 /*
15278 * 1.1 The {base type definition} must be an atomic simple
15279 * type definition or a built-in primitive datatype.
15280 */
15281 if (! WXS_IS_ATOMIC(type->baseType)(type->baseType->flags & 1 << 8)) {
15282 xmlSchemaPCustomErr(pctxt,
15283 XML_SCHEMAP_COS_ST_RESTRICTS_1_1,
15284 WXS_BASIC_CAST(xmlSchemaBasicItemPtr) type, NULL((void*)0),
15285 "The base type '%s' is not an atomic simple type",
15286 xmlSchemaGetComponentQName(&str, type->baseType));
15287 FREE_AND_NULL(str)if ((str) != ((void*)0)) { xmlFree((xmlChar *) (str)); str = (
(void*)0); }
15288 return (XML_SCHEMAP_COS_ST_RESTRICTS_1_1);
15289 }
15290 /* 1.2 The {final} of the {base type definition} must not contain
15291 * restriction.
15292 */
15293 /* OPTIMIZE TODO : This is already done in xmlSchemaCheckStPropsCorrect */
15294 if (xmlSchemaTypeFinalContains(type->baseType,
15295 XML_SCHEMAS_TYPE_FINAL_RESTRICTION1 << 10)) {
15296 xmlSchemaPCustomErr(pctxt,
15297 XML_SCHEMAP_COS_ST_RESTRICTS_1_2,
15298 WXS_BASIC_CAST(xmlSchemaBasicItemPtr) type, NULL((void*)0),
15299 "The final of its base type '%s' must not contain 'restriction'",
15300 xmlSchemaGetComponentQName(&str, type->baseType));
15301 FREE_AND_NULL(str)if ((str) != ((void*)0)) { xmlFree((xmlChar *) (str)); str = (
(void*)0); }
15302 return (XML_SCHEMAP_COS_ST_RESTRICTS_1_2);
15303 }
15304
15305 /*
15306 * 1.3.1 DF must be an allowed constraining facet for the {primitive
15307 * type definition}, as specified in the appropriate subsection of 3.2
15308 * Primitive datatypes.
15309 */
15310 if (type->facets != NULL((void*)0)) {
15311 xmlSchemaFacetPtr facet;
15312 int ok = 1;
15313
15314 primitive = xmlSchemaGetPrimitiveType(type);
15315 if (primitive == NULL((void*)0)) {
15316 PERROR_INT("xmlSchemaCheckCOSSTRestricts",xmlSchemaInternalErr((xmlSchemaAbstractCtxtPtr) pctxt, "xmlSchemaCheckCOSSTRestricts"
, "failed to get primitive type");
15317 "failed to get primitive type")xmlSchemaInternalErr((xmlSchemaAbstractCtxtPtr) pctxt, "xmlSchemaCheckCOSSTRestricts"
, "failed to get primitive type");
;
15318 return (-1);
15319 }
15320 facet = type->facets;
15321 do {
15322 if (xmlSchemaIsBuiltInTypeFacet(primitive, facet->type) == 0) {
15323 ok = 0;
15324 xmlSchemaPIllegalFacetAtomicErr(pctxt,
15325 XML_SCHEMAP_COS_ST_RESTRICTS_1_3_1,
15326 type, primitive, facet);
15327 }
15328 facet = facet->next;
15329 } while (facet != NULL((void*)0));
15330 if (ok == 0)
15331 return (XML_SCHEMAP_COS_ST_RESTRICTS_1_3_1);
15332 }
15333 /*
15334 * SPEC (1.3.2) "If there is a facet of the same kind in the {facets}
15335 * of the {base type definition} (call this BF),then the DF's {value}
15336 * must be a valid restriction of BF's {value} as defined in
15337 * [XML Schemas: Datatypes]."
15338 *
15339 * NOTE (1.3.2) Facet derivation constraints are currently handled in
15340 * xmlSchemaDeriveAndValidateFacets()
15341 */
15342 } else if (WXS_IS_LIST(type)(type->flags & 1 << 6)) {
15343 xmlSchemaTypePtr itemType = NULL((void*)0);
15344
15345 itemType = type->subtypes;
15346 if ((itemType == NULL((void*)0)) || (! WXS_IS_SIMPLE(itemType)((itemType->type == XML_SCHEMA_TYPE_SIMPLE) || ((itemType->
type == XML_SCHEMA_TYPE_BASIC) && (itemType->builtInType
!= XML_SCHEMAS_ANYTYPE)))
)) {
15347 PERROR_INT("xmlSchemaCheckCOSSTRestricts",xmlSchemaInternalErr((xmlSchemaAbstractCtxtPtr) pctxt, "xmlSchemaCheckCOSSTRestricts"
, "failed to evaluate the item type");
15348 "failed to evaluate the item type")xmlSchemaInternalErr((xmlSchemaAbstractCtxtPtr) pctxt, "xmlSchemaCheckCOSSTRestricts"
, "failed to evaluate the item type");
;
15349 return (-1);
15350 }
15351 if (WXS_IS_TYPE_NOT_FIXED(itemType)(((itemType)->type != XML_SCHEMA_TYPE_BASIC) && ((
(itemType)->flags & 1 << 22) == 0))
)
15352 xmlSchemaTypeFixup(itemType, ACTXT_CAST(xmlSchemaAbstractCtxtPtr) pctxt);
15353 /*
15354 * 2.1 The {item type definition} must have a {variety} of atomic or
15355 * union (in which case all the {member type definitions}
15356 * must be atomic).
15357 */
15358 if ((! WXS_IS_ATOMIC(itemType)(itemType->flags & 1 << 8)) &&
15359 (! WXS_IS_UNION(itemType)(itemType->flags & 1 << 7))) {
15360 xmlSchemaPCustomErr(pctxt,
15361 XML_SCHEMAP_COS_ST_RESTRICTS_2_1,
15362 WXS_BASIC_CAST(xmlSchemaBasicItemPtr) type, NULL((void*)0),
15363 "The item type '%s' does not have a variety of atomic or union",
15364 xmlSchemaGetComponentQName(&str, itemType));
15365 FREE_AND_NULL(str)if ((str) != ((void*)0)) { xmlFree((xmlChar *) (str)); str = (
(void*)0); }
15366 return (XML_SCHEMAP_COS_ST_RESTRICTS_2_1);
15367 } else if (WXS_IS_UNION(itemType)(itemType->flags & 1 << 7)) {
15368 xmlSchemaTypeLinkPtr member;
15369
15370 member = itemType->memberTypes;
15371 while (member != NULL((void*)0)) {
15372 if (! WXS_IS_ATOMIC(member->type)(member->type->flags & 1 << 8)) {
15373 xmlSchemaPCustomErr(pctxt,
15374 XML_SCHEMAP_COS_ST_RESTRICTS_2_1,
15375 WXS_BASIC_CAST(xmlSchemaBasicItemPtr) type, NULL((void*)0),
15376 "The item type is a union type, but the "
15377 "member type '%s' of this item type is not atomic",
15378 xmlSchemaGetComponentQName(&str, member->type));
15379 FREE_AND_NULL(str)if ((str) != ((void*)0)) { xmlFree((xmlChar *) (str)); str = (
(void*)0); }
15380 return (XML_SCHEMAP_COS_ST_RESTRICTS_2_1);
15381 }
15382 member = member->next;
15383 }
15384 }
15385
15386 if (WXS_IS_ANY_SIMPLE_TYPE(type->baseType)(((type->baseType)->type == XML_SCHEMA_TYPE_BASIC) &&
((type->baseType)->builtInType == XML_SCHEMAS_ANYSIMPLETYPE
))
) {
15387 xmlSchemaFacetPtr facet;
15388 /*
15389 * This is the case if we have: <simpleType><list ..
15390 */
15391 /*
15392 * 2.3.1
15393 * 2.3.1.1 The {final} of the {item type definition} must not
15394 * contain list.
15395 */
15396 if (xmlSchemaTypeFinalContains(itemType,
15397 XML_SCHEMAS_TYPE_FINAL_LIST1 << 11)) {
15398 xmlSchemaPCustomErr(pctxt,
15399 XML_SCHEMAP_COS_ST_RESTRICTS_2_3_1_1,
15400 WXS_BASIC_CAST(xmlSchemaBasicItemPtr) type, NULL((void*)0),
15401 "The final of its item type '%s' must not contain 'list'",
15402 xmlSchemaGetComponentQName(&str, itemType));
15403 FREE_AND_NULL(str)if ((str) != ((void*)0)) { xmlFree((xmlChar *) (str)); str = (
(void*)0); }
15404 return (XML_SCHEMAP_COS_ST_RESTRICTS_2_3_1_1);
15405 }
15406 /*
15407 * 2.3.1.2 The {facets} must only contain the whiteSpace
15408 * facet component.
15409 * OPTIMIZE TODO: the S4S already disallows any facet
15410 * to be specified.
15411 */
15412 if (type->facets != NULL((void*)0)) {
15413 facet = type->facets;
15414 do {
15415 if (facet->type != XML_SCHEMA_FACET_WHITESPACE) {
15416 xmlSchemaPIllegalFacetListUnionErr(pctxt,
15417 XML_SCHEMAP_COS_ST_RESTRICTS_2_3_1_2,
15418 type, facet);
15419 return (XML_SCHEMAP_COS_ST_RESTRICTS_2_3_1_2);
15420 }
15421 facet = facet->next;
15422 } while (facet != NULL((void*)0));
15423 }
15424 /*
15425 * MAYBE TODO: (Hmm, not really) Datatypes states:
15426 * A `list` datatype can be `derived` from an `atomic` datatype
15427 * whose `lexical space` allows space (such as string or anyURI)or
15428 * a `union` datatype any of whose {member type definitions}'s
15429 * `lexical space` allows space.
15430 */
15431 } else {
15432 /*
15433 * This is the case if we have: <simpleType><restriction ...
15434 * I.e. the variety of "list" is inherited.
15435 */
15436 /*
15437 * 2.3.2
15438 * 2.3.2.1 The {base type definition} must have a {variety} of list.
15439 */
15440 if (! WXS_IS_LIST(type->baseType)(type->baseType->flags & 1 << 6)) {
15441 xmlSchemaPCustomErr(pctxt,
15442 XML_SCHEMAP_COS_ST_RESTRICTS_2_3_2_1,
15443 WXS_BASIC_CAST(xmlSchemaBasicItemPtr) type, NULL((void*)0),
15444 "The base type '%s' must be a list type",
15445 xmlSchemaGetComponentQName(&str, type->baseType));
15446 FREE_AND_NULL(str)if ((str) != ((void*)0)) { xmlFree((xmlChar *) (str)); str = (
(void*)0); }
15447 return (XML_SCHEMAP_COS_ST_RESTRICTS_2_3_2_1);
15448 }
15449 /*
15450 * 2.3.2.2 The {final} of the {base type definition} must not
15451 * contain restriction.
15452 */
15453 if (xmlSchemaTypeFinalContains(type->baseType,
15454 XML_SCHEMAS_TYPE_FINAL_RESTRICTION1 << 10)) {
15455 xmlSchemaPCustomErr(pctxt,
15456 XML_SCHEMAP_COS_ST_RESTRICTS_2_3_2_2,
15457 WXS_BASIC_CAST(xmlSchemaBasicItemPtr) type, NULL((void*)0),
15458 "The 'final' of the base type '%s' must not contain 'restriction'",
15459 xmlSchemaGetComponentQName(&str, type->baseType));
15460 FREE_AND_NULL(str)if ((str) != ((void*)0)) { xmlFree((xmlChar *) (str)); str = (
(void*)0); }
15461 return (XML_SCHEMAP_COS_ST_RESTRICTS_2_3_2_2);
15462 }
15463 /*
15464 * 2.3.2.3 The {item type definition} must be validly derived
15465 * from the {base type definition}'s {item type definition} given
15466 * the empty set, as defined in Type Derivation OK (Simple) ($3.14.6).
15467 */
15468 {
15469 xmlSchemaTypePtr baseItemType;
15470
15471 baseItemType = type->baseType->subtypes;
15472 if ((baseItemType == NULL((void*)0)) || (! WXS_IS_SIMPLE(baseItemType)((baseItemType->type == XML_SCHEMA_TYPE_SIMPLE) || ((baseItemType
->type == XML_SCHEMA_TYPE_BASIC) && (baseItemType->
builtInType != XML_SCHEMAS_ANYTYPE)))
)) {
15473 PERROR_INT("xmlSchemaCheckCOSSTRestricts",xmlSchemaInternalErr((xmlSchemaAbstractCtxtPtr) pctxt, "xmlSchemaCheckCOSSTRestricts"
, "failed to eval the item type of a base type");
15474 "failed to eval the item type of a base type")xmlSchemaInternalErr((xmlSchemaAbstractCtxtPtr) pctxt, "xmlSchemaCheckCOSSTRestricts"
, "failed to eval the item type of a base type");
;
15475 return (-1);
15476 }
15477 if ((itemType != baseItemType) &&
15478 (xmlSchemaCheckCOSSTDerivedOK(ACTXT_CAST(xmlSchemaAbstractCtxtPtr) pctxt, itemType,
15479 baseItemType, 0) != 0)) {
15480 xmlChar *strBIT = NULL((void*)0), *strBT = NULL((void*)0);
15481 xmlSchemaPCustomErrExt(pctxt,
15482 XML_SCHEMAP_COS_ST_RESTRICTS_2_3_2_3,
15483 WXS_BASIC_CAST(xmlSchemaBasicItemPtr) type, NULL((void*)0),
15484 "The item type '%s' is not validly derived from "
15485 "the item type '%s' of the base type '%s'",
15486 xmlSchemaGetComponentQName(&str, itemType),
15487 xmlSchemaGetComponentQName(&strBIT, baseItemType),
15488 xmlSchemaGetComponentQName(&strBT, type->baseType));
15489
15490 FREE_AND_NULL(str)if ((str) != ((void*)0)) { xmlFree((xmlChar *) (str)); str = (
(void*)0); }
15491 FREE_AND_NULL(strBIT)if ((strBIT) != ((void*)0)) { xmlFree((xmlChar *) (strBIT)); strBIT
= ((void*)0); }
15492 FREE_AND_NULL(strBT)if ((strBT) != ((void*)0)) { xmlFree((xmlChar *) (strBT)); strBT
= ((void*)0); }
15493 return (XML_SCHEMAP_COS_ST_RESTRICTS_2_3_2_3);
15494 }
15495 }
15496
15497 if (type->facets != NULL((void*)0)) {
15498 xmlSchemaFacetPtr facet;
15499 int ok = 1;
15500 /*
15501 * 2.3.2.4 Only length, minLength, maxLength, whiteSpace, pattern
15502 * and enumeration facet components are allowed among the {facets}.
15503 */
15504 facet = type->facets;
15505 do {
15506 switch (facet->type) {
15507 case XML_SCHEMA_FACET_LENGTH:
15508 case XML_SCHEMA_FACET_MINLENGTH:
15509 case XML_SCHEMA_FACET_MAXLENGTH:
15510 case XML_SCHEMA_FACET_WHITESPACE:
15511 /*
15512 * TODO: 2.5.1.2 List datatypes
15513 * The value of `whiteSpace` is fixed to the value collapse.
15514 */
15515 case XML_SCHEMA_FACET_PATTERN:
15516 case XML_SCHEMA_FACET_ENUMERATION:
15517 break;
15518 default: {
15519 xmlSchemaPIllegalFacetListUnionErr(pctxt,
15520 XML_SCHEMAP_COS_ST_RESTRICTS_2_3_2_4,
15521 type, facet);
15522 /*
15523 * We could return, but it's nicer to report all
15524 * invalid facets.
15525 */
15526 ok = 0;
15527 }
15528 }
15529 facet = facet->next;
15530 } while (facet != NULL((void*)0));
15531 if (ok == 0)
15532 return (XML_SCHEMAP_COS_ST_RESTRICTS_2_3_2_4);
15533 /*
15534 * SPEC (2.3.2.5) (same as 1.3.2)
15535 *
15536 * NOTE (2.3.2.5) This is currently done in
15537 * xmlSchemaDeriveAndValidateFacets()
15538 */
15539 }
15540 }
15541 } else if (WXS_IS_UNION(type)(type->flags & 1 << 7)) {
15542 /*
15543 * 3.1 The {member type definitions} must all have {variety} of
15544 * atomic or list.
15545 */
15546 xmlSchemaTypeLinkPtr member;
15547
15548 member = type->memberTypes;
15549 while (member != NULL((void*)0)) {
15550 if (WXS_IS_TYPE_NOT_FIXED(member->type)(((member->type)->type != XML_SCHEMA_TYPE_BASIC) &&
(((member->type)->flags & 1 << 22) == 0))
)
15551 xmlSchemaTypeFixup(member->type, ACTXT_CAST(xmlSchemaAbstractCtxtPtr) pctxt);
15552
15553 if ((! WXS_IS_ATOMIC(member->type)(member->type->flags & 1 << 8)) &&
15554 (! WXS_IS_LIST(member->type)(member->type->flags & 1 << 6))) {
15555 xmlSchemaPCustomErr(pctxt,
15556 XML_SCHEMAP_COS_ST_RESTRICTS_3_1,
15557 WXS_BASIC_CAST(xmlSchemaBasicItemPtr) type, NULL((void*)0),
15558 "The member type '%s' is neither an atomic, nor a list type",
15559 xmlSchemaGetComponentQName(&str, member->type));
15560 FREE_AND_NULL(str)if ((str) != ((void*)0)) { xmlFree((xmlChar *) (str)); str = (
(void*)0); }
15561 return (XML_SCHEMAP_COS_ST_RESTRICTS_3_1);
15562 }
15563 member = member->next;
15564 }
15565 /*
15566 * 3.3.1 If the {base type definition} is the `simple ur-type
15567 * definition`
15568 */
15569 if (type->baseType->builtInType == XML_SCHEMAS_ANYSIMPLETYPE) {
15570 /*
15571 * 3.3.1.1 All of the {member type definitions} must have a
15572 * {final} which does not contain union.
15573 */
15574 member = type->memberTypes;
15575 while (member != NULL((void*)0)) {
15576 if (xmlSchemaTypeFinalContains(member->type,
15577 XML_SCHEMAS_TYPE_FINAL_UNION1 << 12)) {
15578 xmlSchemaPCustomErr(pctxt,
15579 XML_SCHEMAP_COS_ST_RESTRICTS_3_3_1,
15580 WXS_BASIC_CAST(xmlSchemaBasicItemPtr) type, NULL((void*)0),
15581 "The 'final' of member type '%s' contains 'union'",
15582 xmlSchemaGetComponentQName(&str, member->type));
15583 FREE_AND_NULL(str)if ((str) != ((void*)0)) { xmlFree((xmlChar *) (str)); str = (
(void*)0); }
15584 return (XML_SCHEMAP_COS_ST_RESTRICTS_3_3_1);
15585 }
15586 member = member->next;
15587 }
15588 /*
15589 * 3.3.1.2 The {facets} must be empty.
15590 */
15591 if (type->facetSet != NULL((void*)0)) {
15592 xmlSchemaPCustomErr(pctxt,
15593 XML_SCHEMAP_COS_ST_RESTRICTS_3_3_1_2,
15594 WXS_BASIC_CAST(xmlSchemaBasicItemPtr) type, NULL((void*)0),
15595 "No facets allowed", NULL((void*)0));
15596 return (XML_SCHEMAP_COS_ST_RESTRICTS_3_3_1_2);
15597 }
15598 } else {
15599 /*
15600 * 3.3.2.1 The {base type definition} must have a {variety} of union.
15601 * I.e. the variety of "list" is inherited.
15602 */
15603 if (! WXS_IS_UNION(type->baseType)(type->baseType->flags & 1 << 7)) {
15604 xmlSchemaPCustomErr(pctxt,
15605 XML_SCHEMAP_COS_ST_RESTRICTS_3_3_2_1,
15606 WXS_BASIC_CAST(xmlSchemaBasicItemPtr) type, NULL((void*)0),
15607 "The base type '%s' is not a union type",
15608 xmlSchemaGetComponentQName(&str, type->baseType));
15609 FREE_AND_NULL(str)if ((str) != ((void*)0)) { xmlFree((xmlChar *) (str)); str = (
(void*)0); }
15610 return (XML_SCHEMAP_COS_ST_RESTRICTS_3_3_2_1);
15611 }
15612 /*
15613 * 3.3.2.2 The {final} of the {base type definition} must not contain restriction.
15614 */
15615 if (xmlSchemaTypeFinalContains(type->baseType,
15616 XML_SCHEMAS_TYPE_FINAL_RESTRICTION1 << 10)) {
15617 xmlSchemaPCustomErr(pctxt,
15618 XML_SCHEMAP_COS_ST_RESTRICTS_3_3_2_2,
15619 WXS_BASIC_CAST(xmlSchemaBasicItemPtr) type, NULL((void*)0),
15620 "The 'final' of its base type '%s' must not contain 'restriction'",
15621 xmlSchemaGetComponentQName(&str, type->baseType));
15622 FREE_AND_NULL(str)if ((str) != ((void*)0)) { xmlFree((xmlChar *) (str)); str = (
(void*)0); }
15623 return (XML_SCHEMAP_COS_ST_RESTRICTS_3_3_2_2);
15624 }
15625 /*
15626 * 3.3.2.3 The {member type definitions}, in order, must be validly
15627 * derived from the corresponding type definitions in the {base
15628 * type definition}'s {member type definitions} given the empty set,
15629 * as defined in Type Derivation OK (Simple) ($3.14.6).
15630 */
15631 {
15632 xmlSchemaTypeLinkPtr baseMember;
15633
15634 /*
15635 * OPTIMIZE: if the type is restricting, it has no local defined
15636 * member types and inherits the member types of the base type;
15637 * thus a check for equality can be skipped.
15638 */
15639 /*
15640 * Even worse: I cannot see a scenario where a restricting
15641 * union simple type can have other member types as the member
15642 * types of it's base type. This check seems not necessary with
15643 * respect to the derivation process in libxml2.
15644 * But necessary if constructing types with an API.
15645 */
15646 if (type->memberTypes != NULL((void*)0)) {
15647 member = type->memberTypes;
15648 baseMember = xmlSchemaGetUnionSimpleTypeMemberTypes(type->baseType);
15649 if ((member == NULL((void*)0)) && (baseMember != NULL((void*)0))) {
15650 PERROR_INT("xmlSchemaCheckCOSSTRestricts",xmlSchemaInternalErr((xmlSchemaAbstractCtxtPtr) pctxt, "xmlSchemaCheckCOSSTRestricts"
, "different number of member types in base");
15651 "different number of member types in base")xmlSchemaInternalErr((xmlSchemaAbstractCtxtPtr) pctxt, "xmlSchemaCheckCOSSTRestricts"
, "different number of member types in base");
;
15652 }
15653 while (member != NULL((void*)0)) {
15654 if (baseMember == NULL((void*)0)) {
15655 PERROR_INT("xmlSchemaCheckCOSSTRestricts",xmlSchemaInternalErr((xmlSchemaAbstractCtxtPtr) pctxt, "xmlSchemaCheckCOSSTRestricts"
, "different number of member types in base");
15656 "different number of member types in base")xmlSchemaInternalErr((xmlSchemaAbstractCtxtPtr) pctxt, "xmlSchemaCheckCOSSTRestricts"
, "different number of member types in base");
;
15657 } else if ((member->type != baseMember->type) &&
15658 (xmlSchemaCheckCOSSTDerivedOK(ACTXT_CAST(xmlSchemaAbstractCtxtPtr) pctxt,
15659 member->type, baseMember->type, 0) != 0)) {
15660 xmlChar *strBMT = NULL((void*)0), *strBT = NULL((void*)0);
15661
15662 xmlSchemaPCustomErrExt(pctxt,
15663 XML_SCHEMAP_COS_ST_RESTRICTS_3_3_2_3,
15664 WXS_BASIC_CAST(xmlSchemaBasicItemPtr) type, NULL((void*)0),
15665 "The member type %s is not validly "
15666 "derived from its corresponding member "
15667 "type %s of the base type %s",
15668 xmlSchemaGetComponentQName(&str, member->type),
15669 xmlSchemaGetComponentQName(&strBMT, baseMember->type),
15670 xmlSchemaGetComponentQName(&strBT, type->baseType));
15671 FREE_AND_NULL(str)if ((str) != ((void*)0)) { xmlFree((xmlChar *) (str)); str = (
(void*)0); }
15672 FREE_AND_NULL(strBMT)if ((strBMT) != ((void*)0)) { xmlFree((xmlChar *) (strBMT)); strBMT
= ((void*)0); }
15673 FREE_AND_NULL(strBT)if ((strBT) != ((void*)0)) { xmlFree((xmlChar *) (strBT)); strBT
= ((void*)0); }
15674 return (XML_SCHEMAP_COS_ST_RESTRICTS_3_3_2_3);
15675 }
15676 member = member->next;
15677 if (baseMember != NULL((void*)0))
15678 baseMember = baseMember->next;
15679 }
15680 }
15681 }
15682 /*
15683 * 3.3.2.4 Only pattern and enumeration facet components are
15684 * allowed among the {facets}.
15685 */
15686 if (type->facets != NULL((void*)0)) {
15687 xmlSchemaFacetPtr facet;
15688 int ok = 1;
15689
15690 facet = type->facets;
15691 do {
15692 if ((facet->type != XML_SCHEMA_FACET_PATTERN) &&
15693 (facet->type != XML_SCHEMA_FACET_ENUMERATION)) {
15694 xmlSchemaPIllegalFacetListUnionErr(pctxt,
15695 XML_SCHEMAP_COS_ST_RESTRICTS_3_3_2_4,
15696 type, facet);
15697 ok = 0;
15698 }
15699 facet = facet->next;
15700 } while (facet != NULL((void*)0));
15701 if (ok == 0)
15702 return (XML_SCHEMAP_COS_ST_RESTRICTS_3_3_2_4);
15703
15704 }
15705 /*
15706 * SPEC (3.3.2.5) (same as 1.3.2)
15707 *
15708 * NOTE (3.3.2.5) This is currently done in
15709 * xmlSchemaDeriveAndValidateFacets()
15710 */
15711 }
15712 }
15713
15714 return (0);
15715}
15716
15717/**
15718 * xmlSchemaCheckSRCSimpleType:
15719 * @ctxt: the schema parser context
15720 * @type: the simple type definition
15721 *
15722 * Checks crc-simple-type constraints.
15723 *
15724 * Returns 0 if the constraints are satisfied,
15725 * if not a positive error code and -1 on internal
15726 * errors.
15727 */
15728#if 0
15729static int
15730xmlSchemaCheckSRCSimpleType(xmlSchemaParserCtxtPtr ctxt,
15731 xmlSchemaTypePtr type)
15732{
15733 /*
15734 * src-simple-type.1 The corresponding simple type definition, if any,
15735 * must satisfy the conditions set out in Constraints on Simple Type
15736 * Definition Schema Components ($3.14.6).
15737 */
15738 if (WXS_IS_RESTRICTION(type)((type)->flags & 1 << 2)) {
15739 /*
15740 * src-simple-type.2 "If the <restriction> alternative is chosen,
15741 * either it must have a base [attribute] or a <simpleType> among its
15742 * [children], but not both."
15743 * NOTE: This is checked in the parse function of <restriction>.
15744 */
15745 /*
15746 *
15747 */
15748 } else if (WXS_IS_LIST(type)(type->flags & 1 << 6)) {
15749 /* src-simple-type.3 "If the <list> alternative is chosen, either it must have
15750 * an itemType [attribute] or a <simpleType> among its [children],
15751 * but not both."
15752 *
15753 * NOTE: This is checked in the parse function of <list>.
15754 */
15755 } else if (WXS_IS_UNION(type)(type->flags & 1 << 7)) {
15756 /*
15757 * src-simple-type.4 is checked in xmlSchemaCheckUnionTypeDefCircular().
15758 */
15759 }
15760 return (0);
15761}
15762#endif
15763
15764static int
15765xmlSchemaCreateVCtxtOnPCtxt(xmlSchemaParserCtxtPtr ctxt)
15766{
15767 if (ctxt->vctxt == NULL((void*)0)) {
15768 ctxt->vctxt = xmlSchemaNewValidCtxt(NULL((void*)0));
15769 if (ctxt->vctxt == NULL((void*)0)) {
15770 xmlSchemaPErr(ctxt, NULL((void*)0),
15771 XML_SCHEMAP_INTERNAL,
15772 "Internal error: xmlSchemaCreateVCtxtOnPCtxt, "
15773 "failed to create a temp. validation context.\n",
15774 NULL((void*)0), NULL((void*)0));
15775 return (-1);
15776 }
15777 /* TODO: Pass user data. */
15778 xmlSchemaSetValidErrors(ctxt->vctxt,
15779 ctxt->error, ctxt->warning, ctxt->errCtxt);
15780 xmlSchemaSetValidStructuredErrors(ctxt->vctxt,
15781 ctxt->serror, ctxt->errCtxt);
15782 }
15783 return (0);
15784}
15785
15786static int
15787xmlSchemaVCheckCVCSimpleType(xmlSchemaAbstractCtxtPtr actxt,
15788 xmlNodePtr node,
15789 xmlSchemaTypePtr type,
15790 const xmlChar *value,
15791 xmlSchemaValPtr *retVal,
15792 int fireErrors,
15793 int normalize,
15794 int isNormalized);
15795
15796/**
15797 * xmlSchemaParseCheckCOSValidDefault:
15798 * @pctxt: the schema parser context
15799 * @type: the simple type definition
15800 * @value: the default value
15801 * @node: an optional node (the holder of the value)
15802 *
15803 * Schema Component Constraint: Element Default Valid (Immediate)
15804 * (cos-valid-default)
15805 * This will be used by the parser only. For the validator there's
15806 * an other version.
15807 *
15808 * Returns 0 if the constraints are satisfied,
15809 * if not, a positive error code and -1 on internal
15810 * errors.
15811 */
15812static int
15813xmlSchemaParseCheckCOSValidDefault(xmlSchemaParserCtxtPtr pctxt,
15814 xmlNodePtr node,
15815 xmlSchemaTypePtr type,
15816 const xmlChar *value,
15817 xmlSchemaValPtr *val)
15818{
15819 int ret = 0;
15820
15821 /*
15822 * cos-valid-default:
15823 * Schema Component Constraint: Element Default Valid (Immediate)
15824 * For a string to be a valid default with respect to a type
15825 * definition the appropriate case among the following must be true:
15826 */
15827 if WXS_IS_COMPLEX(type)(((type)->type == XML_SCHEMA_TYPE_COMPLEX) || ((type)->
builtInType == XML_SCHEMAS_ANYTYPE))
{
15828 /*
15829 * Complex type.
15830 *
15831 * SPEC (2.1) "its {content type} must be a simple type definition
15832 * or mixed."
15833 * SPEC (2.2.2) "If the {content type} is mixed, then the {content
15834 * type}'s particle must be `emptiable` as defined by
15835 * Particle Emptiable ($3.9.6)."
15836 */
15837 if ((! WXS_HAS_SIMPLE_CONTENT(type)((type->contentType == XML_SCHEMA_CONTENT_SIMPLE) || (type
->contentType == XML_SCHEMA_CONTENT_BASIC))
) &&
15838 ((! WXS_HAS_MIXED_CONTENT(type)(type->contentType == XML_SCHEMA_CONTENT_MIXED)) || (! WXS_EMPTIABLE(type)(xmlSchemaIsParticleEmptiable((xmlSchemaParticlePtr) (type)->
subtypes))
))) {
15839 /* NOTE that this covers (2.2.2) as well. */
15840 xmlSchemaPCustomErr(pctxt,
15841 XML_SCHEMAP_COS_VALID_DEFAULT_2_1,
15842 WXS_BASIC_CAST(xmlSchemaBasicItemPtr) type, type->node,
15843 "For a string to be a valid default, the type definition "
15844 "must be a simple type or a complex type with mixed content "
15845 "and a particle emptiable", NULL((void*)0));
15846 return(XML_SCHEMAP_COS_VALID_DEFAULT_2_1);
15847 }
15848 }
15849 /*
15850 * 1 If the type definition is a simple type definition, then the string
15851 * must be `valid` with respect to that definition as defined by String
15852 * Valid ($3.14.4).
15853 *
15854 * AND
15855 *
15856 * 2.2.1 If the {content type} is a simple type definition, then the
15857 * string must be `valid` with respect to that simple type definition
15858 * as defined by String Valid ($3.14.4).
15859 */
15860 if (WXS_IS_SIMPLE(type)((type->type == XML_SCHEMA_TYPE_SIMPLE) || ((type->type
== XML_SCHEMA_TYPE_BASIC) && (type->builtInType !=
XML_SCHEMAS_ANYTYPE)))
)
15861 ret = xmlSchemaVCheckCVCSimpleType(ACTXT_CAST(xmlSchemaAbstractCtxtPtr) pctxt, node,
15862 type, value, val, 1, 1, 0);
15863 else if (WXS_HAS_SIMPLE_CONTENT(type)((type->contentType == XML_SCHEMA_CONTENT_SIMPLE) || (type
->contentType == XML_SCHEMA_CONTENT_BASIC))
)
15864 ret = xmlSchemaVCheckCVCSimpleType(ACTXT_CAST(xmlSchemaAbstractCtxtPtr) pctxt, node,
15865 type->contentTypeDef, value, val, 1, 1, 0);
15866 else
15867 return (ret);
15868
15869 if (ret < 0) {
15870 PERROR_INT("xmlSchemaParseCheckCOSValidDefault",xmlSchemaInternalErr((xmlSchemaAbstractCtxtPtr) pctxt, "xmlSchemaParseCheckCOSValidDefault"
, "calling xmlSchemaVCheckCVCSimpleType()");
15871 "calling xmlSchemaVCheckCVCSimpleType()")xmlSchemaInternalErr((xmlSchemaAbstractCtxtPtr) pctxt, "xmlSchemaParseCheckCOSValidDefault"
, "calling xmlSchemaVCheckCVCSimpleType()");
;
15872 }
15873
15874 return (ret);
15875}
15876
15877/**
15878 * xmlSchemaCheckCTPropsCorrect:
15879 * @ctxt: the schema parser context
15880 * @type: the complex type definition
15881 *
15882 *.(4.6) Constraints on Complex Type Definition Schema Components
15883 * Schema Component Constraint:
15884 * Complex Type Definition Properties Correct (ct-props-correct)
15885 * STATUS: (seems) complete
15886 *
15887 * Returns 0 if the constraints are satisfied, a positive
15888 * error code if not and -1 if an internal error occurred.
15889 */
15890static int
15891xmlSchemaCheckCTPropsCorrect(xmlSchemaParserCtxtPtr pctxt,
15892 xmlSchemaTypePtr type)
15893{
15894 /*
15895 * TODO: Correct the error code; XML_SCHEMAP_SRC_CT_1 is used temporarily.
15896 *
15897 * SPEC (1) "The values of the properties of a complex type definition must
15898 * be as described in the property tableau in The Complex Type Definition
15899 * Schema Component ($3.4.1), modulo the impact of Missing
15900 * Sub-components ($5.3)."
15901 */
15902 if ((type->baseType != NULL((void*)0)) &&
15903 (WXS_IS_SIMPLE(type->baseType)((type->baseType->type == XML_SCHEMA_TYPE_SIMPLE) || ((
type->baseType->type == XML_SCHEMA_TYPE_BASIC) &&
(type->baseType->builtInType != XML_SCHEMAS_ANYTYPE)))
) &&
15904 (WXS_IS_EXTENSION(type)((type)->flags & 1 << 1) == 0)) {
15905 /*
15906 * SPEC (2) "If the {base type definition} is a simple type definition,
15907 * the {derivation method} must be extension."
15908 */
15909 xmlSchemaCustomErr(ACTXT_CAST(xmlSchemaAbstractCtxtPtr) pctxt,
15910 XML_SCHEMAP_SRC_CT_1,
15911 NULL((void*)0), WXS_BASIC_CAST(xmlSchemaBasicItemPtr) type,
15912 "If the base type is a simple type, the derivation method must be "
15913 "'extension'", NULL((void*)0), NULL((void*)0));
15914 return (XML_SCHEMAP_SRC_CT_1);
15915 }
15916 /*
15917 * SPEC (3) "Circular definitions are disallowed, except for the `ur-type
15918 * definition`. That is, it must be possible to reach the `ur-type
15919 * definition` by repeatedly following the {base type definition}."
15920 *
15921 * NOTE (3) is done in xmlSchemaCheckTypeDefCircular().
15922 */
15923 /*
15924 * NOTE that (4) and (5) need the following:
15925 * - attribute uses need to be already inherited (apply attr. prohibitions)
15926 * - attribute group references need to be expanded already
15927 * - simple types need to be typefixed already
15928 */
15929 if (type->attrUses &&
15930 (((xmlSchemaItemListPtr) type->attrUses)->nbItems > 1))
15931 {
15932 xmlSchemaItemListPtr uses = (xmlSchemaItemListPtr) type->attrUses;
15933 xmlSchemaAttributeUsePtr use, tmp;
15934 int i, j, hasId = 0;
15935
15936 for (i = uses->nbItems -1; i >= 0; i--) {
15937 use = uses->items[i];
15938
15939 /*
15940 * SPEC ct-props-correct
15941 * (4) "Two distinct attribute declarations in the
15942 * {attribute uses} must not have identical {name}s and
15943 * {target namespace}s."
15944 */
15945 if (i > 0) {
15946 for (j = i -1; j >= 0; j--) {
15947 tmp = uses->items[j];
15948 if ((WXS_ATTRUSE_DECL_NAME(use)(((xmlSchemaAttributeUsePtr) (use))->attrDecl)->name ==
15949 WXS_ATTRUSE_DECL_NAME(tmp)(((xmlSchemaAttributeUsePtr) (tmp))->attrDecl)->name) &&
15950 (WXS_ATTRUSE_DECL_TNS(use)(((xmlSchemaAttributeUsePtr) (use))->attrDecl)->targetNamespace ==
15951 WXS_ATTRUSE_DECL_TNS(tmp)(((xmlSchemaAttributeUsePtr) (tmp))->attrDecl)->targetNamespace))
15952 {
15953 xmlChar *str = NULL((void*)0);
15954
15955 xmlSchemaCustomErr(ACTXT_CAST(xmlSchemaAbstractCtxtPtr) pctxt,
15956 XML_SCHEMAP_AG_PROPS_CORRECT,
15957 NULL((void*)0), WXS_BASIC_CAST(xmlSchemaBasicItemPtr) type,
15958 "Duplicate %s",
15959 xmlSchemaGetComponentDesignation(&str, use),
15960 NULL((void*)0));
15961 FREE_AND_NULL(str)if ((str) != ((void*)0)) { xmlFree((xmlChar *) (str)); str = (
(void*)0); }
;
15962 /*
15963 * Remove the duplicate.
15964 */
15965 if (xmlSchemaItemListRemove(uses, i) == -1)
15966 goto exit_failure;
15967 goto next_use;
15968 }
15969 }
15970 }
15971 /*
15972 * SPEC ct-props-correct
15973 * (5) "Two distinct attribute declarations in the
15974 * {attribute uses} must not have {type definition}s which
15975 * are or are derived from ID."
15976 */
15977 if (WXS_ATTRUSE_TYPEDEF(use)(((xmlSchemaAttributeUsePtr) ((xmlSchemaAttributeUsePtr) use)
)->attrDecl)->subtypes
!= NULL((void*)0)) {
15978 if (xmlSchemaIsDerivedFromBuiltInType(
15979 WXS_ATTRUSE_TYPEDEF(use)(((xmlSchemaAttributeUsePtr) ((xmlSchemaAttributeUsePtr) use)
)->attrDecl)->subtypes
, XML_SCHEMAS_ID))
15980 {
15981 if (hasId) {
15982 xmlChar *str = NULL((void*)0);
15983
15984 xmlSchemaCustomErr(ACTXT_CAST(xmlSchemaAbstractCtxtPtr) pctxt,
15985 XML_SCHEMAP_AG_PROPS_CORRECT,
15986 NULL((void*)0), WXS_BASIC_CAST(xmlSchemaBasicItemPtr) type,
15987 "There must not exist more than one attribute "
15988 "declaration of type 'xs:ID' "
15989 "(or derived from 'xs:ID'). The %s violates this "
15990 "constraint",
15991 xmlSchemaGetComponentDesignation(&str, use),
15992 NULL((void*)0));
15993 FREE_AND_NULL(str)if ((str) != ((void*)0)) { xmlFree((xmlChar *) (str)); str = (
(void*)0); }
;
15994 if (xmlSchemaItemListRemove(uses, i) == -1)
15995 goto exit_failure;
15996 }
15997
15998 hasId = 1;
15999 }
16000 }
16001next_use: {}
16002 }
16003 }
16004 return (0);
16005exit_failure:
16006 return(-1);
16007}
16008
16009static int
16010xmlSchemaAreEqualTypes(xmlSchemaTypePtr typeA,
16011 xmlSchemaTypePtr typeB)
16012{
16013 /*
16014 * TODO: This should implement component-identity
16015 * in the future.
16016 */
16017 if ((typeA == NULL((void*)0)) || (typeB == NULL((void*)0)))
16018 return (0);
16019 return (typeA == typeB);
16020}
16021
16022/**
16023 * xmlSchemaCheckCOSCTDerivedOK:
16024 * @ctxt: the schema parser context
16025 * @type: the to-be derived complex type definition
16026 * @baseType: the base complex type definition
16027 * @set: the given set
16028 *
16029 * Schema Component Constraint:
16030 * Type Derivation OK (Complex) (cos-ct-derived-ok)
16031 *
16032 * STATUS: completed
16033 *
16034 * Returns 0 if the constraints are satisfied, or 1
16035 * if not.
16036 */
16037static int
16038xmlSchemaCheckCOSCTDerivedOK(xmlSchemaAbstractCtxtPtr actxt,
16039 xmlSchemaTypePtr type,
16040 xmlSchemaTypePtr baseType,
16041 int set)
16042{
16043 int equal = xmlSchemaAreEqualTypes(type, baseType);
16044 /* TODO: Error codes. */
16045 /*
16046 * SPEC "For a complex type definition (call it D, for derived)
16047 * to be validly derived from a type definition (call this
16048 * B, for base) given a subset of {extension, restriction}
16049 * all of the following must be true:"
16050 */
16051 if (! equal) {
16052 /*
16053 * SPEC (1) "If B and D are not the same type definition, then the
16054 * {derivation method} of D must not be in the subset."
16055 */
16056 if (((set & SUBSET_EXTENSION1<<1) && (WXS_IS_EXTENSION(type)((type)->flags & 1 << 1))) ||
16057 ((set & SUBSET_RESTRICTION1<<0) && (WXS_IS_RESTRICTION(type)((type)->flags & 1 << 2))))
16058 return (1);
16059 } else {
16060 /*
16061 * SPEC (2.1) "B and D must be the same type definition."
16062 */
16063 return (0);
16064 }
16065 /*
16066 * SPEC (2.2) "B must be D's {base type definition}."
16067 */
16068 if (type->baseType == baseType)
16069 return (0);
16070 /*
16071 * SPEC (2.3.1) "D's {base type definition} must not be the `ur-type
16072 * definition`."
16073 */
16074 if (WXS_IS_ANYTYPE(type->baseType)(( (type->baseType)->type == XML_SCHEMA_TYPE_BASIC) &&
( ((xmlSchemaTypePtr) (type->baseType))->builtInType ==
XML_SCHEMAS_ANYTYPE))
)
16075 return (1);
16076
16077 if (WXS_IS_COMPLEX(type->baseType)(((type->baseType)->type == XML_SCHEMA_TYPE_COMPLEX) ||
((type->baseType)->builtInType == XML_SCHEMAS_ANYTYPE)
)
) {
16078 /*
16079 * SPEC (2.3.2.1) "If D's {base type definition} is complex, then it
16080 * must be validly derived from B given the subset as defined by this
16081 * constraint."
16082 */
16083 return (xmlSchemaCheckCOSCTDerivedOK(actxt, type->baseType,
16084 baseType, set));
16085 } else {
16086 /*
16087 * SPEC (2.3.2.2) "If D's {base type definition} is simple, then it
16088 * must be validly derived from B given the subset as defined in Type
16089 * Derivation OK (Simple) ($3.14.6).
16090 */
16091 return (xmlSchemaCheckCOSSTDerivedOK(actxt, type->baseType,
16092 baseType, set));
16093 }
16094}
16095
16096/**
16097 * xmlSchemaCheckCOSDerivedOK:
16098 * @type: the derived simple type definition
16099 * @baseType: the base type definition
16100 *
16101 * Calls:
16102 * Type Derivation OK (Simple) AND Type Derivation OK (Complex)
16103 *
16104 * Checks whether @type can be validly derived from @baseType.
16105 *
16106 * Returns 0 on success, an positive error code otherwise.
16107 */
16108static int
16109xmlSchemaCheckCOSDerivedOK(xmlSchemaAbstractCtxtPtr actxt,
16110 xmlSchemaTypePtr type,
16111 xmlSchemaTypePtr baseType,
16112 int set)
16113{
16114 if (WXS_IS_SIMPLE(type)((type->type == XML_SCHEMA_TYPE_SIMPLE) || ((type->type
== XML_SCHEMA_TYPE_BASIC) && (type->builtInType !=
XML_SCHEMAS_ANYTYPE)))
)
16115 return (xmlSchemaCheckCOSSTDerivedOK(actxt, type, baseType, set));
16116 else
16117 return (xmlSchemaCheckCOSCTDerivedOK(actxt, type, baseType, set));
16118}
16119
16120/**
16121 * xmlSchemaCheckCOSCTExtends:
16122 * @ctxt: the schema parser context
16123 * @type: the complex type definition
16124 *
16125 * (3.4.6) Constraints on Complex Type Definition Schema Components
16126 * Schema Component Constraint:
16127 * Derivation Valid (Extension) (cos-ct-extends)
16128 *
16129 * STATUS:
16130 * missing:
16131 * (1.5)
16132 * (1.4.3.2.2.2) "Particle Valid (Extension)"
16133 *
16134 * Returns 0 if the constraints are satisfied, a positive
16135 * error code if not and -1 if an internal error occurred.
16136 */
16137static int
16138xmlSchemaCheckCOSCTExtends(xmlSchemaParserCtxtPtr ctxt,
16139 xmlSchemaTypePtr type)
16140{
16141 xmlSchemaTypePtr base = type->baseType;
16142 /*
16143 * TODO: Correct the error code; XML_SCHEMAP_COS_CT_EXTENDS_1_1 is used
16144 * temporarily only.
16145 */
16146 /*
16147 * SPEC (1) "If the {base type definition} is a complex type definition,
16148 * then all of the following must be true:"
16149 */
16150 if (WXS_IS_COMPLEX(base)(((base)->type == XML_SCHEMA_TYPE_COMPLEX) || ((base)->
builtInType == XML_SCHEMAS_ANYTYPE))
) {
16151 /*
16152 * SPEC (1.1) "The {final} of the {base type definition} must not
16153 * contain extension."
16154 */
16155 if (base->flags & XML_SCHEMAS_TYPE_FINAL_EXTENSION1 << 9) {
16156 xmlSchemaPCustomErr(ctxt,
16157 XML_SCHEMAP_COS_CT_EXTENDS_1_1,
16158 WXS_BASIC_CAST(xmlSchemaBasicItemPtr) type, NULL((void*)0),
16159 "The 'final' of the base type definition "
16160 "contains 'extension'", NULL((void*)0));
16161 return (XML_SCHEMAP_COS_CT_EXTENDS_1_1);
16162 }
16163
16164 /*
16165 * ATTENTION: The constrains (1.2) and (1.3) are not applied,
16166 * since they are automatically satisfied through the
16167 * inheriting mechanism.
16168 * Note that even if redefining components, the inheriting mechanism
16169 * is used.
16170 */
16171#if 0
16172 /*
16173 * SPEC (1.2) "Its {attribute uses} must be a subset of the {attribute
16174 * uses}
16175 * of the complex type definition itself, that is, for every attribute
16176 * use in the {attribute uses} of the {base type definition}, there
16177 * must be an attribute use in the {attribute uses} of the complex
16178 * type definition itself whose {attribute declaration} has the same
16179 * {name}, {target namespace} and {type definition} as its attribute
16180 * declaration"
16181 */
16182 if (base->attrUses != NULL((void*)0)) {
16183 int i, j, found;
16184 xmlSchemaAttributeUsePtr use, buse;
16185
16186 for (i = 0; i < (WXS_LIST_CAST(xmlSchemaItemListPtr) base->attrUses)->nbItems; i ++) {
16187 buse = (WXS_LIST_CAST(xmlSchemaItemListPtr) base->attrUses)->items[i];
16188 found = 0;
16189 if (type->attrUses != NULL((void*)0)) {
16190 use = (WXS_LIST_CAST(xmlSchemaItemListPtr) type->attrUses)->items[j];
16191 for (j = 0; j < (WXS_LIST_CAST(xmlSchemaItemListPtr) type->attrUses)->nbItems; j ++)
16192 {
16193 if ((WXS_ATTRUSE_DECL_NAME(use)(((xmlSchemaAttributeUsePtr) (use))->attrDecl)->name ==
16194 WXS_ATTRUSE_DECL_NAME(buse)(((xmlSchemaAttributeUsePtr) (buse))->attrDecl)->name) &&
16195 (WXS_ATTRUSE_DECL_TNS(use)(((xmlSchemaAttributeUsePtr) (use))->attrDecl)->targetNamespace ==
16196 WXS_ATTRUSE_DECL_TNS(buse)(((xmlSchemaAttributeUsePtr) (buse))->attrDecl)->targetNamespace) &&
16197 (WXS_ATTRUSE_TYPEDEF(use)(((xmlSchemaAttributeUsePtr) ((xmlSchemaAttributeUsePtr) use)
)->attrDecl)->subtypes
==
16198 WXS_ATTRUSE_TYPEDEF(buse)(((xmlSchemaAttributeUsePtr) ((xmlSchemaAttributeUsePtr) buse
))->attrDecl)->subtypes
)
16199 {
16200 found = 1;
16201 break;
16202 }
16203 }
16204 }
16205 if (! found) {
16206 xmlChar *str = NULL((void*)0);
16207
16208 xmlSchemaCustomErr(ACTXT_CAST(xmlSchemaAbstractCtxtPtr) ctxt,
16209 XML_SCHEMAP_COS_CT_EXTENDS_1_2,
16210 NULL((void*)0), WXS_BASIC_CAST(xmlSchemaBasicItemPtr) type,
16211 /*
16212 * TODO: The report does not indicate that also the
16213 * type needs to be the same.
16214 */
16215 "This type is missing a matching correspondent "
16216 "for its {base type}'s %s in its {attribute uses}",
16217 xmlSchemaGetComponentDesignation(&str,
16218 buse->children),
16219 NULL((void*)0));
16220 FREE_AND_NULL(str)if ((str) != ((void*)0)) { xmlFree((xmlChar *) (str)); str = (
(void*)0); }
16221 }
16222 }
16223 }
16224 /*
16225 * SPEC (1.3) "If it has an {attribute wildcard}, the complex type
16226 * definition must also have one, and the base type definition's
16227 * {attribute wildcard}'s {namespace constraint} must be a subset
16228 * of the complex type definition's {attribute wildcard}'s {namespace
16229 * constraint}, as defined by Wildcard Subset ($3.10.6)."
16230 */
16231
16232 /*
16233 * MAYBE TODO: Enable if ever needed. But this will be needed only
16234 * if created the type via a schema construction API.
16235 */
16236 if (base->attributeWildcard != NULL((void*)0)) {
16237 if (type->attributeWildcard == NULL((void*)0)) {
16238 xmlChar *str = NULL((void*)0);
16239
16240 xmlSchemaCustomErr(ACTXT_CAST(xmlSchemaAbstractCtxtPtr) pctxt,
16241 XML_SCHEMAP_COS_CT_EXTENDS_1_3,
16242 NULL((void*)0), type,
16243 "The base %s has an attribute wildcard, "
16244 "but this type is missing an attribute wildcard",
16245 xmlSchemaGetComponentDesignation(&str, base));
16246 FREE_AND_NULL(str)if ((str) != ((void*)0)) { xmlFree((xmlChar *) (str)); str = (
(void*)0); }
16247
16248 } else if (xmlSchemaCheckCOSNSSubset(
16249 base->attributeWildcard, type->attributeWildcard))
16250 {
16251 xmlChar *str = NULL((void*)0);
16252
16253 xmlSchemaCustomErr(ACTXT_CAST(xmlSchemaAbstractCtxtPtr) pctxt,
16254 XML_SCHEMAP_COS_CT_EXTENDS_1_3,
16255 NULL((void*)0), type,
16256 "The attribute wildcard is not a valid "
16257 "superset of the one in the base %s",
16258 xmlSchemaGetComponentDesignation(&str, base));
16259 FREE_AND_NULL(str)if ((str) != ((void*)0)) { xmlFree((xmlChar *) (str)); str = (
(void*)0); }
16260 }
16261 }
16262#endif
16263 /*
16264 * SPEC (1.4) "One of the following must be true:"
16265 */
16266 if ((type->contentTypeDef != NULL((void*)0)) &&
16267 (type->contentTypeDef == base->contentTypeDef)) {
16268 /*
16269 * SPEC (1.4.1) "The {content type} of the {base type definition}
16270 * and the {content type} of the complex type definition itself
16271 * must be the same simple type definition"
16272 * PASS
16273 */
16274 } else if ((type->contentType == XML_SCHEMA_CONTENT_EMPTY) &&
16275 (base->contentType == XML_SCHEMA_CONTENT_EMPTY) ) {
16276 /*
16277 * SPEC (1.4.2) "The {content type} of both the {base type
16278 * definition} and the complex type definition itself must
16279 * be empty."
16280 * PASS
16281 */
16282 } else {
16283 /*
16284 * SPEC (1.4.3) "All of the following must be true:"
16285 */
16286 if (type->subtypes == NULL((void*)0)) {
16287 /*
16288 * SPEC 1.4.3.1 The {content type} of the complex type
16289 * definition itself must specify a particle.
16290 */
16291 xmlSchemaPCustomErr(ctxt,
16292 XML_SCHEMAP_COS_CT_EXTENDS_1_1,
16293 WXS_BASIC_CAST(xmlSchemaBasicItemPtr) type, NULL((void*)0),
16294 "The content type must specify a particle", NULL((void*)0));
16295 return (XML_SCHEMAP_COS_CT_EXTENDS_1_1);
16296 }
16297 /*
16298 * SPEC (1.4.3.2) "One of the following must be true:"
16299 */
16300 if (base->contentType == XML_SCHEMA_CONTENT_EMPTY) {
16301 /*
16302 * SPEC (1.4.3.2.1) "The {content type} of the {base type
16303 * definition} must be empty.
16304 * PASS
16305 */
16306 } else {
16307 /*
16308 * SPEC (1.4.3.2.2) "All of the following must be true:"
16309 */
16310 if ((type->contentType != base->contentType) ||
16311 ((type->contentType != XML_SCHEMA_CONTENT_MIXED) &&
16312 (type->contentType != XML_SCHEMA_CONTENT_ELEMENTS))) {
16313 /*
16314 * SPEC (1.4.3.2.2.1) "Both {content type}s must be mixed
16315 * or both must be element-only."
16316 */
16317 xmlSchemaPCustomErr(ctxt,
16318 XML_SCHEMAP_COS_CT_EXTENDS_1_1,
16319 WXS_BASIC_CAST(xmlSchemaBasicItemPtr) type, NULL((void*)0),
16320 "The content type of both, the type and its base "
16321 "type, must either 'mixed' or 'element-only'", NULL((void*)0));
16322 return (XML_SCHEMAP_COS_CT_EXTENDS_1_1);
16323 }
16324 /*
16325 * URGENT TODO SPEC (1.4.3.2.2.2) "The particle of the
16326 * complex type definition must be a `valid extension`
16327 * of the {base type definition}'s particle, as defined
16328 * in Particle Valid (Extension) ($3.9.6)."
16329 *
16330 * NOTE that we won't check "Particle Valid (Extension)",
16331 * since it is ensured by the derivation process in
16332 * xmlSchemaTypeFixup(). We need to implement this when heading
16333 * for a construction API
16334 * TODO: !! This is needed to be checked if redefining a type !!
16335 */
16336 }
16337 /*
16338 * URGENT TODO (1.5)
16339 */
16340 }
16341 } else {
16342 /*
16343 * SPEC (2) "If the {base type definition} is a simple type definition,
16344 * then all of the following must be true:"
16345 */
16346 if (type->contentTypeDef != base) {
16347 /*
16348 * SPEC (2.1) "The {content type} must be the same simple type
16349 * definition."
16350 */
16351 xmlSchemaPCustomErr(ctxt,
16352 XML_SCHEMAP_COS_CT_EXTENDS_1_1,
16353 WXS_BASIC_CAST(xmlSchemaBasicItemPtr) type, NULL((void*)0),
16354 "The content type must be the simple base type", NULL((void*)0));
16355 return (XML_SCHEMAP_COS_CT_EXTENDS_1_1);
16356 }
16357 if (base->flags & XML_SCHEMAS_TYPE_FINAL_EXTENSION1 << 9) {
16358 /*
16359 * SPEC (2.2) "The {final} of the {base type definition} must not
16360 * contain extension"
16361 * NOTE that this is the same as (1.1).
16362 */
16363 xmlSchemaPCustomErr(ctxt,
16364 XML_SCHEMAP_COS_CT_EXTENDS_1_1,
16365 WXS_BASIC_CAST(xmlSchemaBasicItemPtr) type, NULL((void*)0),
16366 "The 'final' of the base type definition "
16367 "contains 'extension'", NULL((void*)0));
16368 return (XML_SCHEMAP_COS_CT_EXTENDS_1_1);
16369 }
16370 }
16371 return (0);
16372}
16373
16374/**
16375 * xmlSchemaCheckDerivationOKRestriction:
16376 * @ctxt: the schema parser context
16377 * @type: the complex type definition
16378 *
16379 * (3.4.6) Constraints on Complex Type Definition Schema Components
16380 * Schema Component Constraint:
16381 * Derivation Valid (Restriction, Complex) (derivation-ok-restriction)
16382 *
16383 * STATUS:
16384 * missing:
16385 * (5.4.2) ???
16386 *
16387 * ATTENTION:
16388 * In XML Schema 1.1 this will be:
16389 * Validation Rule: Checking complex type subsumption
16390 *
16391 * Returns 0 if the constraints are satisfied, a positive
16392 * error code if not and -1 if an internal error occurred.
16393 */
16394static int
16395xmlSchemaCheckDerivationOKRestriction(xmlSchemaParserCtxtPtr ctxt,
16396 xmlSchemaTypePtr type)
16397{
16398 xmlSchemaTypePtr base;
16399
16400 /*
16401 * TODO: Correct the error code; XML_SCHEMAP_DERIVATION_OK_RESTRICTION_1 is used
16402 * temporarily only.
16403 */
16404 base = type->baseType;
16405 if (! WXS_IS_COMPLEX(base)(((base)->type == XML_SCHEMA_TYPE_COMPLEX) || ((base)->
builtInType == XML_SCHEMAS_ANYTYPE))
) {
16406 xmlSchemaCustomErr(ACTXT_CAST(xmlSchemaAbstractCtxtPtr) ctxt,
16407 XML_SCHEMAP_DERIVATION_OK_RESTRICTION_1,
16408 type->node, WXS_BASIC_CAST(xmlSchemaBasicItemPtr) type,
16409 "The base type must be a complex type", NULL((void*)0), NULL((void*)0));
16410 return(ctxt->err);
16411 }
16412 if (base->flags & XML_SCHEMAS_TYPE_FINAL_RESTRICTION1 << 10) {
16413 /*
16414 * SPEC (1) "The {base type definition} must be a complex type
16415 * definition whose {final} does not contain restriction."
16416 */
16417 xmlSchemaCustomErr(ACTXT_CAST(xmlSchemaAbstractCtxtPtr) ctxt,
16418 XML_SCHEMAP_DERIVATION_OK_RESTRICTION_1,
16419 type->node, WXS_BASIC_CAST(xmlSchemaBasicItemPtr) type,
16420 "The 'final' of the base type definition "
16421 "contains 'restriction'", NULL((void*)0), NULL((void*)0));
16422 return (ctxt->err);
16423 }
16424 /*
16425 * SPEC (2), (3) and (4)
16426 * Those are handled in a separate function, since the
16427 * same constraints are needed for redefinition of
16428 * attribute groups as well.
16429 */
16430 if (xmlSchemaCheckDerivationOKRestriction2to4(ctxt,
16431 XML_SCHEMA_ACTION_DERIVE0,
16432 WXS_BASIC_CAST(xmlSchemaBasicItemPtr) type, WXS_BASIC_CAST(xmlSchemaBasicItemPtr) base,
16433 type->attrUses, base->attrUses,
16434 type->attributeWildcard,
16435 base->attributeWildcard) == -1)
16436 {
16437 return(-1);
16438 }
16439 /*
16440 * SPEC (5) "One of the following must be true:"
16441 */
16442 if (base->builtInType == XML_SCHEMAS_ANYTYPE) {
16443 /*
16444 * SPEC (5.1) "The {base type definition} must be the
16445 * `ur-type definition`."
16446 * PASS
16447 */
16448 } else if ((type->contentType == XML_SCHEMA_CONTENT_SIMPLE) ||
16449 (type->contentType == XML_SCHEMA_CONTENT_BASIC)) {
16450 /*
16451 * SPEC (5.2.1) "The {content type} of the complex type definition
16452 * must be a simple type definition"
16453 *
16454 * SPEC (5.2.2) "One of the following must be true:"
16455 */
16456 if ((base->contentType == XML_SCHEMA_CONTENT_SIMPLE) ||
16457 (base->contentType == XML_SCHEMA_CONTENT_BASIC))
16458 {
16459 int err;
16460 /*
16461 * SPEC (5.2.2.1) "The {content type} of the {base type
16462 * definition} must be a simple type definition from which
16463 * the {content type} is validly derived given the empty
16464 * set as defined in Type Derivation OK (Simple) ($3.14.6)."
16465 *
16466 * ATTENTION TODO: This seems not needed if the type implicitly
16467 * derived from the base type.
16468 *
16469 */
16470 err = xmlSchemaCheckCOSSTDerivedOK(ACTXT_CAST(xmlSchemaAbstractCtxtPtr) ctxt,
16471 type->contentTypeDef, base->contentTypeDef, 0);
16472 if (err != 0) {
16473 xmlChar *strA = NULL((void*)0), *strB = NULL((void*)0);
16474
16475 if (err == -1)
16476 return(-1);
16477 xmlSchemaCustomErr(ACTXT_CAST(xmlSchemaAbstractCtxtPtr) ctxt,
16478 XML_SCHEMAP_DERIVATION_OK_RESTRICTION_1,
16479 NULL((void*)0), WXS_BASIC_CAST(xmlSchemaBasicItemPtr) type,
16480 "The {content type} %s is not validly derived from the "
16481 "base type's {content type} %s",
16482 xmlSchemaGetComponentDesignation(&strA,
16483 type->contentTypeDef),
16484 xmlSchemaGetComponentDesignation(&strB,
16485 base->contentTypeDef));
16486 FREE_AND_NULL(strA)if ((strA) != ((void*)0)) { xmlFree((xmlChar *) (strA)); strA
= ((void*)0); }
;
16487 FREE_AND_NULL(strB)if ((strB) != ((void*)0)) { xmlFree((xmlChar *) (strB)); strB
= ((void*)0); }
;
16488 return(ctxt->err);
16489 }
16490 } else if ((base->contentType == XML_SCHEMA_CONTENT_MIXED) &&
16491 (xmlSchemaIsParticleEmptiable(
16492 (xmlSchemaParticlePtr) base->subtypes))) {
16493 /*
16494 * SPEC (5.2.2.2) "The {base type definition} must be mixed
16495 * and have a particle which is `emptiable` as defined in
16496 * Particle Emptiable ($3.9.6)."
16497 * PASS
16498 */
16499 } else {
16500 xmlSchemaPCustomErr(ctxt,
16501 XML_SCHEMAP_DERIVATION_OK_RESTRICTION_1,
16502 WXS_BASIC_CAST(xmlSchemaBasicItemPtr) type, NULL((void*)0),
16503 "The content type of the base type must be either "
16504 "a simple type or 'mixed' and an emptiable particle", NULL((void*)0));
16505 return (ctxt->err);
16506 }
16507 } else if (type->contentType == XML_SCHEMA_CONTENT_EMPTY) {
16508 /*
16509 * SPEC (5.3.1) "The {content type} of the complex type itself must
16510 * be empty"
16511 */
16512 if (base->contentType == XML_SCHEMA_CONTENT_EMPTY) {
16513 /*
16514 * SPEC (5.3.2.1) "The {content type} of the {base type
16515 * definition} must also be empty."
16516 * PASS
16517 */
16518 } else if (((base->contentType == XML_SCHEMA_CONTENT_ELEMENTS) ||
16519 (base->contentType == XML_SCHEMA_CONTENT_MIXED)) &&
16520 xmlSchemaIsParticleEmptiable(
16521 (xmlSchemaParticlePtr) base->subtypes)) {
16522 /*
16523 * SPEC (5.3.2.2) "The {content type} of the {base type
16524 * definition} must be elementOnly or mixed and have a particle
16525 * which is `emptiable` as defined in Particle Emptiable ($3.9.6)."
16526 * PASS
16527 */
16528 } else {
16529 xmlSchemaPCustomErr(ctxt,
16530 XML_SCHEMAP_DERIVATION_OK_RESTRICTION_1,
16531 WXS_BASIC_CAST(xmlSchemaBasicItemPtr) type, NULL((void*)0),
16532 "The content type of the base type must be either "
16533 "empty or 'mixed' (or 'elements-only') and an emptiable "
16534 "particle", NULL((void*)0));
16535 return (ctxt->err);
16536 }
16537 } else if ((type->contentType == XML_SCHEMA_CONTENT_ELEMENTS) ||
16538 WXS_HAS_MIXED_CONTENT(type)(type->contentType == XML_SCHEMA_CONTENT_MIXED)) {
16539 /*
16540 * SPEC (5.4.1.1) "The {content type} of the complex type definition
16541 * itself must be element-only"
16542 */
16543 if (WXS_HAS_MIXED_CONTENT(type)(type->contentType == XML_SCHEMA_CONTENT_MIXED) && (! WXS_HAS_MIXED_CONTENT(base)(base->contentType == XML_SCHEMA_CONTENT_MIXED))) {
16544 /*
16545 * SPEC (5.4.1.2) "The {content type} of the complex type
16546 * definition itself and of the {base type definition} must be
16547 * mixed"
16548 */
16549 xmlSchemaPCustomErr(ctxt,
16550 XML_SCHEMAP_DERIVATION_OK_RESTRICTION_1,
16551 WXS_BASIC_CAST(xmlSchemaBasicItemPtr) type, NULL((void*)0),
16552 "If the content type is 'mixed', then the content type of the "
16553 "base type must also be 'mixed'", NULL((void*)0));
16554 return (ctxt->err);
16555 }
16556 /*
16557 * SPEC (5.4.2) "The particle of the complex type definition itself
16558 * must be a `valid restriction` of the particle of the {content
16559 * type} of the {base type definition} as defined in Particle Valid
16560 * (Restriction) ($3.9.6).
16561 *
16562 * URGENT TODO: (5.4.2)
16563 */
16564 } else {
16565 xmlSchemaPCustomErr(ctxt,
16566 XML_SCHEMAP_DERIVATION_OK_RESTRICTION_1,
16567 WXS_BASIC_CAST(xmlSchemaBasicItemPtr) type, NULL((void*)0),
16568 "The type is not a valid restriction of its base type", NULL((void*)0));
16569 return (ctxt->err);
16570 }
16571 return (0);
16572}
16573
16574/**
16575 * xmlSchemaCheckCTComponent:
16576 * @ctxt: the schema parser context
16577 * @type: the complex type definition
16578 *
16579 * (3.4.6) Constraints on Complex Type Definition Schema Components
16580 *
16581 * Returns 0 if the constraints are satisfied, a positive
16582 * error code if not and -1 if an internal error occurred.
16583 */
16584static int
16585xmlSchemaCheckCTComponent(xmlSchemaParserCtxtPtr ctxt,
16586 xmlSchemaTypePtr type)
16587{
16588 int ret;
16589 /*
16590 * Complex Type Definition Properties Correct
16591 */
16592 ret = xmlSchemaCheckCTPropsCorrect(ctxt, type);
16593 if (ret != 0)
16594 return (ret);
16595 if (WXS_IS_EXTENSION(type)((type)->flags & 1 << 1))
16596 ret = xmlSchemaCheckCOSCTExtends(ctxt, type);
16597 else
16598 ret = xmlSchemaCheckDerivationOKRestriction(ctxt, type);
16599 return (ret);
16600}
16601
16602/**
16603 * xmlSchemaCheckSRCCT:
16604 * @ctxt: the schema parser context
16605 * @type: the complex type definition
16606 *
16607 * (3.4.3) Constraints on XML Representations of Complex Type Definitions:
16608 * Schema Representation Constraint:
16609 * Complex Type Definition Representation OK (src-ct)
16610 *
16611 * Returns 0 if the constraints are satisfied, a positive
16612 * error code if not and -1 if an internal error occurred.
16613 */
16614static int
16615xmlSchemaCheckSRCCT(xmlSchemaParserCtxtPtr ctxt,
16616 xmlSchemaTypePtr type)
16617{
16618 xmlSchemaTypePtr base;
16619 int ret = 0;
16620
16621 /*
16622 * TODO: Adjust the error codes here, as I used
16623 * XML_SCHEMAP_SRC_CT_1 only yet.
16624 */
16625 base = type->baseType;
16626 if (! WXS_HAS_SIMPLE_CONTENT(type)((type->contentType == XML_SCHEMA_CONTENT_SIMPLE) || (type
->contentType == XML_SCHEMA_CONTENT_BASIC))
) {
16627 /*
16628 * 1 If the <complexContent> alternative is chosen, the type definition
16629 * `resolved` to by the `actual value` of the base [attribute]
16630 * must be a complex type definition;
16631 */
16632 if (! WXS_IS_COMPLEX(base)(((base)->type == XML_SCHEMA_TYPE_COMPLEX) || ((base)->
builtInType == XML_SCHEMAS_ANYTYPE))
) {
16633 xmlChar *str = NULL((void*)0);
16634 xmlSchemaPCustomErr(ctxt,
16635 XML_SCHEMAP_SRC_CT_1,
16636 WXS_BASIC_CAST(xmlSchemaBasicItemPtr) type, type->node,
16637 "If using <complexContent>, the base type is expected to be "
16638 "a complex type. The base type '%s' is a simple type",
16639 xmlSchemaFormatQName(&str, base->targetNamespace,
16640 base->name));
16641 FREE_AND_NULL(str)if ((str) != ((void*)0)) { xmlFree((xmlChar *) (str)); str = (
(void*)0); }
16642 return (XML_SCHEMAP_SRC_CT_1);
16643 }
16644 } else {
16645 /*
16646 * SPEC
16647 * 2 If the <simpleContent> alternative is chosen, all of the
16648 * following must be true:
16649 * 2.1 The type definition `resolved` to by the `actual value` of the
16650 * base [attribute] must be one of the following:
16651 */
16652 if (WXS_IS_SIMPLE(base)((base->type == XML_SCHEMA_TYPE_SIMPLE) || ((base->type
== XML_SCHEMA_TYPE_BASIC) && (base->builtInType !=
XML_SCHEMAS_ANYTYPE)))
) {
16653 if (WXS_IS_EXTENSION(type)((type)->flags & 1 << 1) == 0) {
16654 xmlChar *str = NULL((void*)0);
16655 /*
16656 * 2.1.3 only if the <extension> alternative is also
16657 * chosen, a simple type definition.
16658 */
16659 /* TODO: Change error code to ..._SRC_CT_2_1_3. */
16660 xmlSchemaPCustomErr(ctxt,
16661 XML_SCHEMAP_SRC_CT_1,
16662 WXS_BASIC_CAST(xmlSchemaBasicItemPtr) type, NULL((void*)0),
16663 "If using <simpleContent> and <restriction>, the base "
16664 "type must be a complex type. The base type '%s' is "
16665 "a simple type",
16666 xmlSchemaFormatQName(&str, base->targetNamespace,
16667 base->name));
16668 FREE_AND_NULL(str)if ((str) != ((void*)0)) { xmlFree((xmlChar *) (str)); str = (
(void*)0); }
16669 return (XML_SCHEMAP_SRC_CT_1);
16670 }
16671 } else {
16672 /* Base type is a complex type. */
16673 if ((base->contentType == XML_SCHEMA_CONTENT_SIMPLE) ||
16674 (base->contentType == XML_SCHEMA_CONTENT_BASIC)) {
16675 /*
16676 * 2.1.1 a complex type definition whose {content type} is a
16677 * simple type definition;
16678 * PASS
16679 */
16680 if (base->contentTypeDef == NULL((void*)0)) {
16681 xmlSchemaPCustomErr(ctxt, XML_SCHEMAP_INTERNAL,
16682 WXS_BASIC_CAST(xmlSchemaBasicItemPtr) type, NULL((void*)0),
16683 "Internal error: xmlSchemaCheckSRCCT, "
16684 "'%s', base type has no content type",
16685 type->name);
16686 return (-1);
16687 }
16688 } else if ((base->contentType == XML_SCHEMA_CONTENT_MIXED) &&
16689 (WXS_IS_RESTRICTION(type)((type)->flags & 1 << 2))) {
16690
16691 /*
16692 * 2.1.2 only if the <restriction> alternative is also
16693 * chosen, a complex type definition whose {content type}
16694 * is mixed and a particle emptiable.
16695 */
16696 if (! xmlSchemaIsParticleEmptiable(
16697 (xmlSchemaParticlePtr) base->subtypes)) {
16698 ret = XML_SCHEMAP_SRC_CT_1;
16699 } else
16700 /*
16701 * Attention: at this point the <simpleType> child is in
16702 * ->contentTypeDef (put there during parsing).
16703 */
16704 if (type->contentTypeDef == NULL((void*)0)) {
16705 xmlChar *str = NULL((void*)0);
16706 /*
16707 * 2.2 If clause 2.1.2 above is satisfied, then there
16708 * must be a <simpleType> among the [children] of
16709 * <restriction>.
16710 */
16711 /* TODO: Change error code to ..._SRC_CT_2_2. */
16712 xmlSchemaPCustomErr(ctxt,
16713 XML_SCHEMAP_SRC_CT_1,
16714 WXS_BASIC_CAST(xmlSchemaBasicItemPtr) type, NULL((void*)0),
16715 "A <simpleType> is expected among the children "
16716 "of <restriction>, if <simpleContent> is used and "
16717 "the base type '%s' is a complex type",
16718 xmlSchemaFormatQName(&str, base->targetNamespace,
16719 base->name));
16720 FREE_AND_NULL(str)if ((str) != ((void*)0)) { xmlFree((xmlChar *) (str)); str = (
(void*)0); }
16721 return (XML_SCHEMAP_SRC_CT_1);
16722 }
16723 } else {
16724 ret = XML_SCHEMAP_SRC_CT_1;
16725 }
16726 }
16727 if (ret > 0) {
16728 xmlChar *str = NULL((void*)0);
16729 if (WXS_IS_RESTRICTION(type)((type)->flags & 1 << 2)) {
16730 xmlSchemaPCustomErr(ctxt,
16731 XML_SCHEMAP_SRC_CT_1,
16732 WXS_BASIC_CAST(xmlSchemaBasicItemPtr) type, NULL((void*)0),
16733 "If <simpleContent> and <restriction> is used, the "
16734 "base type must be a simple type or a complex type with "
16735 "mixed content and particle emptiable. The base type "
16736 "'%s' is none of those",
16737 xmlSchemaFormatQName(&str, base->targetNamespace,
16738 base->name));
16739 } else {
16740 xmlSchemaPCustomErr(ctxt,
16741 XML_SCHEMAP_SRC_CT_1,
16742 WXS_BASIC_CAST(xmlSchemaBasicItemPtr) type, NULL((void*)0),
16743 "If <simpleContent> and <extension> is used, the "
16744 "base type must be a simple type. The base type '%s' "
16745 "is a complex type",
16746 xmlSchemaFormatQName(&str, base->targetNamespace,
16747 base->name));
16748 }
16749 FREE_AND_NULL(str)if ((str) != ((void*)0)) { xmlFree((xmlChar *) (str)); str = (
(void*)0); }
16750 }
16751 }
16752 /*
16753 * SPEC (3) "The corresponding complex type definition component must
16754 * satisfy the conditions set out in Constraints on Complex Type
16755 * Definition Schema Components ($3.4.6);"
16756 * NOTE (3) will be done in xmlSchemaTypeFixup().
16757 */
16758 /*
16759 * SPEC (4) If clause 2.2.1 or clause 2.2.2 in the correspondence specification
16760 * above for {attribute wildcard} is satisfied, the intensional
16761 * intersection must be expressible, as defined in Attribute Wildcard
16762 * Intersection ($3.10.6).
16763 * NOTE (4) is done in xmlSchemaFixupTypeAttributeUses().
16764 */
16765 return (ret);
16766}
16767
16768#ifdef ENABLE_PARTICLE_RESTRICTION
16769/**
16770 * xmlSchemaCheckParticleRangeOK:
16771 * @ctxt: the schema parser context
16772 * @type: the complex type definition
16773 *
16774 * (3.9.6) Constraints on Particle Schema Components
16775 * Schema Component Constraint:
16776 * Occurrence Range OK (range-ok)
16777 *
16778 * STATUS: complete
16779 *
16780 * Returns 0 if the constraints are satisfied, a positive
16781 * error code if not and -1 if an internal error occurred.
16782 */
16783static int
16784xmlSchemaCheckParticleRangeOK(int rmin, int rmax,
16785 int bmin, int bmax)
16786{
16787 if (rmin < bmin)
16788 return (1);
16789 if ((bmax != UNBOUNDED(1 << 30)) &&
16790 (rmax > bmax))
16791 return (1);
16792 return (0);
16793}
16794
16795/**
16796 * xmlSchemaCheckRCaseNameAndTypeOK:
16797 * @ctxt: the schema parser context
16798 * @r: the restricting element declaration particle
16799 * @b: the base element declaration particle
16800 *
16801 * (3.9.6) Constraints on Particle Schema Components
16802 * Schema Component Constraint:
16803 * Particle Restriction OK (Elt:Elt -- NameAndTypeOK)
16804 * (rcase-NameAndTypeOK)
16805 *
16806 * STATUS:
16807 * MISSING (3.2.3)
16808 * CLARIFY: (3.2.2)
16809 *
16810 * Returns 0 if the constraints are satisfied, a positive
16811 * error code if not and -1 if an internal error occurred.
16812 */
16813static int
16814xmlSchemaCheckRCaseNameAndTypeOK(xmlSchemaParserCtxtPtr ctxt,
16815 xmlSchemaParticlePtr r,
16816 xmlSchemaParticlePtr b)
16817{
16818 xmlSchemaElementPtr elemR, elemB;
16819
16820 /* TODO: Error codes (rcase-NameAndTypeOK). */
16821 elemR = (xmlSchemaElementPtr) r->children;
16822 elemB = (xmlSchemaElementPtr) b->children;
16823 /*
16824 * SPEC (1) "The declarations' {name}s and {target namespace}s are
16825 * the same."
16826 */
16827 if ((elemR != elemB) &&
16828 ((! xmlStrEqual(elemR->name, elemB->name)) ||
16829 (! xmlStrEqual(elemR->targetNamespace, elemB->targetNamespace))))
16830 return (1);
16831 /*
16832 * SPEC (2) "R's occurrence range is a valid restriction of B's
16833 * occurrence range as defined by Occurrence Range OK ($3.9.6)."
16834 */
16835 if (xmlSchemaCheckParticleRangeOK(r->minOccurs, r->maxOccurs,
16836 b->minOccurs, b->maxOccurs) != 0)
16837 return (1);
16838 /*
16839 * SPEC (3.1) "Both B's declaration's {scope} and R's declaration's
16840 * {scope} are global."
16841 */
16842 if (elemR == elemB)
16843 return (0);
16844 /*
16845 * SPEC (3.2.1) "Either B's {nillable} is true or R's {nillable} is false."
16846 */
16847 if (((elemB->flags & XML_SCHEMAS_ELEM_NILLABLE1 << 0) == 0) &&
16848 (elemR->flags & XML_SCHEMAS_ELEM_NILLABLE1 << 0))
16849 return (1);
16850 /*
16851 * SPEC (3.2.2) "either B's declaration's {value constraint} is absent,
16852 * or is not fixed, or R's declaration's {value constraint} is fixed
16853 * with the same value."
16854 */
16855 if ((elemB->value != NULL((void*)0)) && (elemB->flags & XML_SCHEMAS_ELEM_FIXED1 << 3) &&
16856 ((elemR->value == NULL((void*)0)) ||
16857 ((elemR->flags & XML_SCHEMAS_ELEM_FIXED1 << 3) == 0) ||
16858 /* TODO: Equality of the initial value or normalized or canonical? */
16859 (! xmlStrEqual(elemR->value, elemB->value))))
16860 return (1);
16861 /*
16862 * TODO: SPEC (3.2.3) "R's declaration's {identity-constraint
16863 * definitions} is a subset of B's declaration's {identity-constraint
16864 * definitions}, if any."
16865 */
16866 if (elemB->idcs != NULL((void*)0)) {
16867 /* TODO */
16868 }
16869 /*
16870 * SPEC (3.2.4) "R's declaration's {disallowed substitutions} is a
16871 * superset of B's declaration's {disallowed substitutions}."
16872 */
16873 if (((elemB->flags & XML_SCHEMAS_ELEM_BLOCK_EXTENSION1 << 11) &&
16874 ((elemR->flags & XML_SCHEMAS_ELEM_BLOCK_EXTENSION1 << 11) == 0)) ||
16875 ((elemB->flags & XML_SCHEMAS_ELEM_BLOCK_RESTRICTION1 << 12) &&
16876 ((elemR->flags & XML_SCHEMAS_ELEM_BLOCK_RESTRICTION1 << 12) == 0)) ||
16877 ((elemB->flags & XML_SCHEMAS_ELEM_BLOCK_SUBSTITUTION1 << 13) &&
16878 ((elemR->flags & XML_SCHEMAS_ELEM_BLOCK_SUBSTITUTION1 << 13) == 0)))
16879 return (1);
16880 /*
16881 * SPEC (3.2.5) "R's {type definition} is validly derived given
16882 * {extension, list, union} from B's {type definition}"
16883 *
16884 * BADSPEC TODO: What's the point of adding "list" and "union" to the
16885 * set, if the corresponding constraints handle "restriction" and
16886 * "extension" only?
16887 *
16888 */
16889 {
16890 int set = 0;
16891
16892 set |= SUBSET_EXTENSION1<<1;
16893 set |= SUBSET_LIST1<<3;
16894 set |= SUBSET_UNION1<<4;
16895 if (xmlSchemaCheckCOSDerivedOK(ACTXT_CAST(xmlSchemaAbstractCtxtPtr) ctxt, elemR->subtypes,
16896 elemB->subtypes, set) != 0)
16897 return (1);
16898 }
16899 return (0);
16900}
16901
16902/**
16903 * xmlSchemaCheckRCaseNSCompat:
16904 * @ctxt: the schema parser context
16905 * @r: the restricting element declaration particle
16906 * @b: the base wildcard particle
16907 *
16908 * (3.9.6) Constraints on Particle Schema Components
16909 * Schema Component Constraint:
16910 * Particle Derivation OK (Elt:Any -- NSCompat)
16911 * (rcase-NSCompat)
16912 *
16913 * STATUS: complete
16914 *
16915 * Returns 0 if the constraints are satisfied, a positive
16916 * error code if not and -1 if an internal error occurred.
16917 */
16918static int
16919xmlSchemaCheckRCaseNSCompat(xmlSchemaParserCtxtPtr ctxt,
16920 xmlSchemaParticlePtr r,
16921 xmlSchemaParticlePtr b)
16922{
16923 /* TODO:Error codes (rcase-NSCompat). */
16924 /*
16925 * SPEC "For an element declaration particle to be a `valid restriction`
16926 * of a wildcard particle all of the following must be true:"
16927 *
16928 * SPEC (1) "The element declaration's {target namespace} is `valid`
16929 * with respect to the wildcard's {namespace constraint} as defined by
16930 * Wildcard allows Namespace Name ($3.10.4)."
16931 */
16932 if (xmlSchemaCheckCVCWildcardNamespace((xmlSchemaWildcardPtr) b->children,
16933 ((xmlSchemaElementPtr) r->children)->targetNamespace) != 0)
16934 return (1);
16935 /*
16936 * SPEC (2) "R's occurrence range is a valid restriction of B's
16937 * occurrence range as defined by Occurrence Range OK ($3.9.6)."
16938 */
16939 if (xmlSchemaCheckParticleRangeOK(r->minOccurs, r->maxOccurs,
16940 b->minOccurs, b->maxOccurs) != 0)
16941 return (1);
16942
16943 return (0);
16944}
16945
16946/**
16947 * xmlSchemaCheckRCaseRecurseAsIfGroup:
16948 * @ctxt: the schema parser context
16949 * @r: the restricting element declaration particle
16950 * @b: the base model group particle
16951 *
16952 * (3.9.6) Constraints on Particle Schema Components
16953 * Schema Component Constraint:
16954 * Particle Derivation OK (Elt:All/Choice/Sequence -- RecurseAsIfGroup)
16955 * (rcase-RecurseAsIfGroup)
16956 *
16957 * STATUS: TODO
16958 *
16959 * Returns 0 if the constraints are satisfied, a positive
16960 * error code if not and -1 if an internal error occurred.
16961 */
16962static int
16963xmlSchemaCheckRCaseRecurseAsIfGroup(xmlSchemaParserCtxtPtr ctxt,
16964 xmlSchemaParticlePtr r,
16965 xmlSchemaParticlePtr b)
16966{
16967 /* TODO: Error codes (rcase-RecurseAsIfGroup). */
16968 TODO(*__xmlGenericError())((*__xmlGenericErrorContext()), "Unimplemented block at %s:%d\n"
, "xmlschemas.c", 16968);
16969 return (0);
16970}
16971
16972/**
16973 * xmlSchemaCheckRCaseNSSubset:
16974 * @ctxt: the schema parser context
16975 * @r: the restricting wildcard particle
16976 * @b: the base wildcard particle
16977 *
16978 * (3.9.6) Constraints on Particle Schema Components
16979 * Schema Component Constraint:
16980 * Particle Derivation OK (Any:Any -- NSSubset)
16981 * (rcase-NSSubset)
16982 *
16983 * STATUS: complete
16984 *
16985 * Returns 0 if the constraints are satisfied, a positive
16986 * error code if not and -1 if an internal error occurred.
16987 */
16988static int
16989xmlSchemaCheckRCaseNSSubset(xmlSchemaParserCtxtPtr ctxt,
16990 xmlSchemaParticlePtr r,
16991 xmlSchemaParticlePtr b,
16992 int isAnyTypeBase)
16993{
16994 /* TODO: Error codes (rcase-NSSubset). */
16995 /*
16996 * SPEC (1) "R's occurrence range is a valid restriction of B's
16997 * occurrence range as defined by Occurrence Range OK ($3.9.6)."
16998 */
16999 if (xmlSchemaCheckParticleRangeOK(r->minOccurs, r->maxOccurs,
17000 b->minOccurs, b->maxOccurs))
17001 return (1);
17002 /*
17003 * SPEC (2) "R's {namespace constraint} must be an intensional subset
17004 * of B's {namespace constraint} as defined by Wildcard Subset ($3.10.6)."
17005 */
17006 if (xmlSchemaCheckCOSNSSubset((xmlSchemaWildcardPtr) r->children,
17007 (xmlSchemaWildcardPtr) b->children))
17008 return (1);
17009 /*
17010 * SPEC (3) "Unless B is the content model wildcard of the `ur-type
17011 * definition`, R's {process contents} must be identical to or stronger
17012 * than B's {process contents}, where strict is stronger than lax is
17013 * stronger than skip."
17014 */
17015 if (! isAnyTypeBase) {
17016 if ( ((xmlSchemaWildcardPtr) r->children)->processContents <
17017 ((xmlSchemaWildcardPtr) b->children)->processContents)
17018 return (1);
17019 }
17020
17021 return (0);
17022}
17023
17024/**
17025 * xmlSchemaCheckCOSParticleRestrict:
17026 * @ctxt: the schema parser context
17027 * @type: the complex type definition
17028 *
17029 * (3.9.6) Constraints on Particle Schema Components
17030 * Schema Component Constraint:
17031 * Particle Valid (Restriction) (cos-particle-restrict)
17032 *
17033 * STATUS: TODO
17034 *
17035 * Returns 0 if the constraints are satisfied, a positive
17036 * error code if not and -1 if an internal error occurred.
17037 */
17038static int
17039xmlSchemaCheckCOSParticleRestrict(xmlSchemaParserCtxtPtr ctxt,
17040 xmlSchemaParticlePtr r,
17041 xmlSchemaParticlePtr b)
17042{
17043 int ret = 0;
17044
17045 /*part = WXS_TYPE_PARTICLE(type);
17046 basePart = WXS_TYPE_PARTICLE(base);
17047 */
17048
17049 TODO(*__xmlGenericError())((*__xmlGenericErrorContext()), "Unimplemented block at %s:%d\n"
, "xmlschemas.c", 17049);
17050
17051 /*
17052 * SPEC (1) "They are the same particle."
17053 */
17054 if (r == b)
17055 return (0);
17056
17057
17058 return (0);
17059}
17060
17061#if 0
17062/**
17063 * xmlSchemaCheckRCaseNSRecurseCheckCardinality:
17064 * @ctxt: the schema parser context
17065 * @r: the model group particle
17066 * @b: the base wildcard particle
17067 *
17068 * (3.9.6) Constraints on Particle Schema Components
17069 * Schema Component Constraint:
17070 * Particle Derivation OK (All/Choice/Sequence:Any --
17071 * NSRecurseCheckCardinality)
17072 * (rcase-NSRecurseCheckCardinality)
17073 *
17074 * STATUS: TODO: subst-groups
17075 *
17076 * Returns 0 if the constraints are satisfied, a positive
17077 * error code if not and -1 if an internal error occurred.
17078 */
17079static int
17080xmlSchemaCheckRCaseNSRecurseCheckCardinality(xmlSchemaParserCtxtPtr ctxt,
17081 xmlSchemaParticlePtr r,
17082 xmlSchemaParticlePtr b)
17083{
17084 xmlSchemaParticlePtr part;
17085 /* TODO: Error codes (rcase-NSRecurseCheckCardinality). */
17086 if ((r->children == NULL((void*)0)) || (r->children->children == NULL((void*)0)))
17087 return (-1);
17088 /*
17089 * SPEC "For a group particle to be a `valid restriction` of a
17090 * wildcard particle..."
17091 *
17092 * SPEC (1) "Every member of the {particles} of the group is a `valid
17093 * restriction` of the wildcard as defined by
17094 * Particle Valid (Restriction) ($3.9.6)."
17095 */
17096 part = (xmlSchemaParticlePtr) r->children->children;
17097 do {
17098 if (xmlSchemaCheckCOSParticleRestrict(ctxt, part, b))
17099 return (1);
17100 part = (xmlSchemaParticlePtr) part->next;
17101 } while (part != NULL((void*)0));
17102 /*
17103 * SPEC (2) "The effective total range of the group [...] is a
17104 * valid restriction of B's occurrence range as defined by
17105 * Occurrence Range OK ($3.9.6)."
17106 */
17107 if (xmlSchemaCheckParticleRangeOK(
17108 xmlSchemaGetParticleTotalRangeMin(r),
17109 xmlSchemaGetParticleTotalRangeMax(r),
17110 b->minOccurs, b->maxOccurs) != 0)
17111 return (1);
17112 return (0);
17113}
17114#endif
17115
17116/**
17117 * xmlSchemaCheckRCaseRecurse:
17118 * @ctxt: the schema parser context
17119 * @r: the <all> or <sequence> model group particle
17120 * @b: the base <all> or <sequence> model group particle
17121 *
17122 * (3.9.6) Constraints on Particle Schema Components
17123 * Schema Component Constraint:
17124 * Particle Derivation OK (All:All,Sequence:Sequence --
17125 Recurse)
17126 * (rcase-Recurse)
17127 *
17128 * STATUS: ?
17129 * TODO: subst-groups
17130 *
17131 * Returns 0 if the constraints are satisfied, a positive
17132 * error code if not and -1 if an internal error occurred.
17133 */
17134static int
17135xmlSchemaCheckRCaseRecurse(xmlSchemaParserCtxtPtr ctxt,
17136 xmlSchemaParticlePtr r,
17137 xmlSchemaParticlePtr b)
17138{
17139 /* xmlSchemaParticlePtr part; */
17140 /* TODO: Error codes (rcase-Recurse). */
17141 if ((r->children == NULL((void*)0)) || (b->children == NULL((void*)0)) ||
17142 (r->children->type != b->children->type))
17143 return (-1);
17144 /*
17145 * SPEC "For an all or sequence group particle to be a `valid
17146 * restriction` of another group particle with the same {compositor}..."
17147 *
17148 * SPEC (1) "R's occurrence range is a valid restriction of B's
17149 * occurrence range as defined by Occurrence Range OK ($3.9.6)."
17150 */
17151 if (xmlSchemaCheckParticleRangeOK(r->minOccurs, r->maxOccurs,
17152 b->minOccurs, b->maxOccurs))
17153 return (1);
17154
17155
17156 return (0);
17157}
17158
17159#endif
17160
17161#define FACET_RESTR_MUTUAL_ERR(fac1, fac2)xmlSchemaPCustomErrExt(pctxt, XML_SCHEMAP_INVALID_FACET_VALUE
, (xmlSchemaBasicItemPtr) fac1, fac1->node, "It is an error for both '%s' and '%s' to be specified on the "
"same type definition", (xmlChar *) xmlSchemaFacetTypeToString
(fac1->type), (xmlChar *) xmlSchemaFacetTypeToString(fac2->
type), ((void*)0));
\
17162 xmlSchemaPCustomErrExt(pctxt, \
17163 XML_SCHEMAP_INVALID_FACET_VALUE, \
17164 WXS_BASIC_CAST(xmlSchemaBasicItemPtr) fac1, fac1->node, \
17165 "It is an error for both '%s' and '%s' to be specified on the "\
17166 "same type definition", \
17167 BAD_CAST(xmlChar *) xmlSchemaFacetTypeToString(fac1->type), \
17168 BAD_CAST(xmlChar *) xmlSchemaFacetTypeToString(fac2->type), NULL((void*)0));
17169
17170#define FACET_RESTR_ERR(fac1, msg)xmlSchemaPCustomErr(pctxt, XML_SCHEMAP_INVALID_FACET_VALUE, (
xmlSchemaBasicItemPtr) fac1, fac1->node, msg, ((void*)0));
\
17171 xmlSchemaPCustomErr(pctxt, \
17172 XML_SCHEMAP_INVALID_FACET_VALUE, \
17173 WXS_BASIC_CAST(xmlSchemaBasicItemPtr) fac1, fac1->node, \
17174 msg, NULL((void*)0));
17175
17176#define FACET_RESTR_FIXED_ERR(fac)xmlSchemaPCustomErr(pctxt, XML_SCHEMAP_INVALID_FACET_VALUE, (
xmlSchemaBasicItemPtr) fac, fac->node, "The base type's facet is 'fixed', thus the value must not "
"differ", ((void*)0));
\
17177 xmlSchemaPCustomErr(pctxt, \
17178 XML_SCHEMAP_INVALID_FACET_VALUE, \
17179 WXS_BASIC_CAST(xmlSchemaBasicItemPtr) fac, fac->node, \
17180 "The base type's facet is 'fixed', thus the value must not " \
17181 "differ", NULL((void*)0));
17182
17183static void
17184xmlSchemaDeriveFacetErr(xmlSchemaParserCtxtPtr pctxt,
17185 xmlSchemaFacetPtr facet1,
17186 xmlSchemaFacetPtr facet2,
17187 int lessGreater,
17188 int orEqual,
17189 int ofBase)
17190{
17191 xmlChar *msg = NULL((void*)0);
17192
17193 msg = xmlStrdup(BAD_CAST(xmlChar *) "'");
17194 msg = xmlStrcat(msg, xmlSchemaFacetTypeToString(facet1->type));
17195 msg = xmlStrcat(msg, BAD_CAST(xmlChar *) "' has to be");
17196 if (lessGreater == 0)
17197 msg = xmlStrcat(msg, BAD_CAST(xmlChar *) " equal to");
17198 if (lessGreater == 1)
17199 msg = xmlStrcat(msg, BAD_CAST(xmlChar *) " greater than");
17200 else
17201 msg = xmlStrcat(msg, BAD_CAST(xmlChar *) " less than");
17202
17203 if (orEqual)
17204 msg = xmlStrcat(msg, BAD_CAST(xmlChar *) " or equal to");
17205 msg = xmlStrcat(msg, BAD_CAST(xmlChar *) " '");
17206 msg = xmlStrcat(msg, xmlSchemaFacetTypeToString(facet2->type));
17207 if (ofBase)
17208 msg = xmlStrcat(msg, BAD_CAST(xmlChar *) "' of the base type");
17209 else
17210 msg = xmlStrcat(msg, BAD_CAST(xmlChar *) "'");
17211
17212 xmlSchemaPCustomErr(pctxt,
17213 XML_SCHEMAP_INVALID_FACET_VALUE,
17214 WXS_BASIC_CAST(xmlSchemaBasicItemPtr) facet1, NULL((void*)0),
17215 (const char *) msg, NULL((void*)0));
17216
17217 if (msg != NULL((void*)0))
17218 xmlFree(msg);
17219}
17220
17221/*
17222* xmlSchemaDeriveAndValidateFacets:
17223*
17224* Schema Component Constraint: Simple Type Restriction (Facets)
17225* (st-restrict-facets)
17226*/
17227static int
17228xmlSchemaDeriveAndValidateFacets(xmlSchemaParserCtxtPtr pctxt,
17229 xmlSchemaTypePtr type)
17230{
17231 xmlSchemaTypePtr base = type->baseType;
17232 xmlSchemaFacetLinkPtr link, cur, last = NULL((void*)0);
17233 xmlSchemaFacetPtr facet, bfacet,
17234 flength = NULL((void*)0), ftotdig = NULL((void*)0), ffracdig = NULL((void*)0),
17235 fmaxlen = NULL((void*)0), fminlen = NULL((void*)0), /* facets of the current type */
17236 fmininc = NULL((void*)0), fmaxinc = NULL((void*)0),
17237 fminexc = NULL((void*)0), fmaxexc = NULL((void*)0),
17238 bflength = NULL((void*)0), bftotdig = NULL((void*)0), bffracdig = NULL((void*)0),
17239 bfmaxlen = NULL((void*)0), bfminlen = NULL((void*)0), /* facets of the base type */
17240 bfmininc = NULL((void*)0), bfmaxinc = NULL((void*)0),
17241 bfminexc = NULL((void*)0), bfmaxexc = NULL((void*)0);
17242 int res; /* err = 0, fixedErr; */
17243
17244 /*
17245 * SPEC st-restrict-facets 1:
17246 * "The {variety} of R is the same as that of B."
17247 */
17248 /*
17249 * SPEC st-restrict-facets 2:
17250 * "If {variety} is atomic, the {primitive type definition}
17251 * of R is the same as that of B."
17252 *
17253 * NOTE: we leave 1 & 2 out for now, since this will be
17254 * satisfied by the derivation process.
17255 * CONSTRUCTION TODO: Maybe needed if using a construction API.
17256 */
17257 /*
17258 * SPEC st-restrict-facets 3:
17259 * "The {facets} of R are the union of S and the {facets}
17260 * of B, eliminating duplicates. To eliminate duplicates,
17261 * when a facet of the same kind occurs in both S and the
17262 * {facets} of B, the one in the {facets} of B is not
17263 * included, with the exception of enumeration and pattern
17264 * facets, for which multiple occurrences with distinct values
17265 * are allowed."
17266 */
17267
17268 if ((type->facetSet == NULL((void*)0)) && (base->facetSet == NULL((void*)0)))
17269 return (0);
17270
17271 last = type->facetSet;
17272 if (last != NULL((void*)0))
17273 while (last->next != NULL((void*)0))
17274 last = last->next;
17275
17276 for (cur = type->facetSet; cur != NULL((void*)0); cur = cur->next) {
17277 facet = cur->facet;
17278 switch (facet->type) {
17279 case XML_SCHEMA_FACET_LENGTH:
17280 flength = facet; break;
17281 case XML_SCHEMA_FACET_MINLENGTH:
17282 fminlen = facet; break;
17283 case XML_SCHEMA_FACET_MININCLUSIVE:
17284 fmininc = facet; break;
17285 case XML_SCHEMA_FACET_MINEXCLUSIVE:
17286 fminexc = facet; break;
17287 case XML_SCHEMA_FACET_MAXLENGTH:
17288 fmaxlen = facet; break;
17289 case XML_SCHEMA_FACET_MAXINCLUSIVE:
17290 fmaxinc = facet; break;
17291 case XML_SCHEMA_FACET_MAXEXCLUSIVE:
17292 fmaxexc = facet; break;
17293 case XML_SCHEMA_FACET_TOTALDIGITS:
17294 ftotdig = facet; break;
17295 case XML_SCHEMA_FACET_FRACTIONDIGITS:
17296 ffracdig = facet; break;
17297 default:
17298 break;
17299 }
17300 }
17301 for (cur = base->facetSet; cur != NULL((void*)0); cur = cur->next) {
17302 facet = cur->facet;
17303 switch (facet->type) {
17304 case XML_SCHEMA_FACET_LENGTH:
17305 bflength = facet; break;
17306 case XML_SCHEMA_FACET_MINLENGTH:
17307 bfminlen = facet; break;
17308 case XML_SCHEMA_FACET_MININCLUSIVE:
17309 bfmininc = facet; break;
17310 case XML_SCHEMA_FACET_MINEXCLUSIVE:
17311 bfminexc = facet; break;
17312 case XML_SCHEMA_FACET_MAXLENGTH:
17313 bfmaxlen = facet; break;
17314 case XML_SCHEMA_FACET_MAXINCLUSIVE:
17315 bfmaxinc = facet; break;
17316 case XML_SCHEMA_FACET_MAXEXCLUSIVE:
17317 bfmaxexc = facet; break;
17318 case XML_SCHEMA_FACET_TOTALDIGITS:
17319 bftotdig = facet; break;
17320 case XML_SCHEMA_FACET_FRACTIONDIGITS:
17321 bffracdig = facet; break;
17322 default:
17323 break;
17324 }
17325 }
17326 /*
17327 * length and minLength or maxLength (2.2) + (3.2)
17328 */
17329 if (flength && (fminlen || fmaxlen)) {
17330 FACET_RESTR_ERR(flength, "It is an error for both 'length' and "xmlSchemaPCustomErr(pctxt, XML_SCHEMAP_INVALID_FACET_VALUE, (
xmlSchemaBasicItemPtr) flength, flength->node, "It is an error for both 'length' and "
"either of 'minLength' or 'maxLength' to be specified on " "the same type definition"
, ((void*)0));
17331 "either of 'minLength' or 'maxLength' to be specified on "xmlSchemaPCustomErr(pctxt, XML_SCHEMAP_INVALID_FACET_VALUE, (
xmlSchemaBasicItemPtr) flength, flength->node, "It is an error for both 'length' and "
"either of 'minLength' or 'maxLength' to be specified on " "the same type definition"
, ((void*)0));
17332 "the same type definition")xmlSchemaPCustomErr(pctxt, XML_SCHEMAP_INVALID_FACET_VALUE, (
xmlSchemaBasicItemPtr) flength, flength->node, "It is an error for both 'length' and "
"either of 'minLength' or 'maxLength' to be specified on " "the same type definition"
, ((void*)0));
17333 }
17334 /*
17335 * Mutual exclusions in the same derivation step.
17336 */
17337 if ((fmaxinc) && (fmaxexc)) {
17338 /*
17339 * SCC "maxInclusive and maxExclusive"
17340 */
17341 FACET_RESTR_MUTUAL_ERR(fmaxinc, fmaxexc)xmlSchemaPCustomErrExt(pctxt, XML_SCHEMAP_INVALID_FACET_VALUE
, (xmlSchemaBasicItemPtr) fmaxinc, fmaxinc->node, "It is an error for both '%s' and '%s' to be specified on the "
"same type definition", (xmlChar *) xmlSchemaFacetTypeToString
(fmaxinc->type), (xmlChar *) xmlSchemaFacetTypeToString(fmaxexc
->type), ((void*)0));
17342 }
17343 if ((fmininc) && (fminexc)) {
17344 /*
17345 * SCC "minInclusive and minExclusive"
17346 */
17347 FACET_RESTR_MUTUAL_ERR(fmininc, fminexc)xmlSchemaPCustomErrExt(pctxt, XML_SCHEMAP_INVALID_FACET_VALUE
, (xmlSchemaBasicItemPtr) fmininc, fmininc->node, "It is an error for both '%s' and '%s' to be specified on the "
"same type definition", (xmlChar *) xmlSchemaFacetTypeToString
(fmininc->type), (xmlChar *) xmlSchemaFacetTypeToString(fminexc
->type), ((void*)0));
17348 }
17349
17350 if (flength && bflength) {
17351 /*
17352 * SCC "length valid restriction"
17353 * The values have to be equal.
17354 */
17355 res = xmlSchemaCompareValues(flength->val, bflength->val);
17356 if (res == -2)
17357 goto internal_error;
17358 if (res != 0)
17359 xmlSchemaDeriveFacetErr(pctxt, flength, bflength, 0, 0, 1);
17360 if ((res != 0) && (bflength->fixed)) {
17361 FACET_RESTR_FIXED_ERR(flength)xmlSchemaPCustomErr(pctxt, XML_SCHEMAP_INVALID_FACET_VALUE, (
xmlSchemaBasicItemPtr) flength, flength->node, "The base type's facet is 'fixed', thus the value must not "
"differ", ((void*)0));
17362 }
17363
17364 }
17365 if (fminlen && bfminlen) {
17366 /*
17367 * SCC "minLength valid restriction"
17368 * minLength >= BASE minLength
17369 */
17370 res = xmlSchemaCompareValues(fminlen->val, bfminlen->val);
17371 if (res == -2)
17372 goto internal_error;
17373 if (res == -1)
17374 xmlSchemaDeriveFacetErr(pctxt, fminlen, bfminlen, 1, 1, 1);
17375 if ((res != 0) && (bfminlen->fixed)) {
17376 FACET_RESTR_FIXED_ERR(fminlen)xmlSchemaPCustomErr(pctxt, XML_SCHEMAP_INVALID_FACET_VALUE, (
xmlSchemaBasicItemPtr) fminlen, fminlen->node, "The base type's facet is 'fixed', thus the value must not "
"differ", ((void*)0));
17377 }
17378 }
17379 if (fmaxlen && bfmaxlen) {
17380 /*
17381 * SCC "maxLength valid restriction"
17382 * maxLength <= BASE minLength
17383 */
17384 res = xmlSchemaCompareValues(fmaxlen->val, bfmaxlen->val);
17385 if (res == -2)
17386 goto internal_error;
17387 if (res == 1)
17388 xmlSchemaDeriveFacetErr(pctxt, fmaxlen, bfmaxlen, -1, 1, 1);
17389 if ((res != 0) && (bfmaxlen->fixed)) {
17390 FACET_RESTR_FIXED_ERR(fmaxlen)xmlSchemaPCustomErr(pctxt, XML_SCHEMAP_INVALID_FACET_VALUE, (
xmlSchemaBasicItemPtr) fmaxlen, fmaxlen->node, "The base type's facet is 'fixed', thus the value must not "
"differ", ((void*)0));
17391 }
17392 }
17393 /*
17394 * SCC "length and minLength or maxLength"
17395 */
17396 if (! flength)
17397 flength = bflength;
17398 if (flength) {
17399 if (! fminlen)
17400 fminlen = bfminlen;
17401 if (fminlen) {
17402 /* (1.1) length >= minLength */
17403 res = xmlSchemaCompareValues(flength->val, fminlen->val);
17404 if (res == -2)
17405 goto internal_error;
17406 if (res == -1)
17407 xmlSchemaDeriveFacetErr(pctxt, flength, fminlen, 1, 1, 0);
17408 }
17409 if (! fmaxlen)
17410 fmaxlen = bfmaxlen;
17411 if (fmaxlen) {
17412 /* (2.1) length <= maxLength */
17413 res = xmlSchemaCompareValues(flength->val, fmaxlen->val);
17414 if (res == -2)
17415 goto internal_error;
17416 if (res == 1)
17417 xmlSchemaDeriveFacetErr(pctxt, flength, fmaxlen, -1, 1, 0);
17418 }
17419 }
17420 if (fmaxinc) {
17421 /*
17422 * "maxInclusive"
17423 */
17424 if (fmininc) {
17425 /* SCC "maxInclusive >= minInclusive" */
17426 res = xmlSchemaCompareValues(fmaxinc->val, fmininc->val);
17427 if (res == -2)
17428 goto internal_error;
17429 if (res == -1) {
17430 xmlSchemaDeriveFacetErr(pctxt, fmaxinc, fmininc, 1, 1, 0);
17431 }
17432 }
17433 /*
17434 * SCC "maxInclusive valid restriction"
17435 */
17436 if (bfmaxinc) {
17437 /* maxInclusive <= BASE maxInclusive */
17438 res = xmlSchemaCompareValues(fmaxinc->val, bfmaxinc->val);
17439 if (res == -2)
17440 goto internal_error;
17441 if (res == 1)
17442 xmlSchemaDeriveFacetErr(pctxt, fmaxinc, bfmaxinc, -1, 1, 1);
17443 if ((res != 0) && (bfmaxinc->fixed)) {
17444 FACET_RESTR_FIXED_ERR(fmaxinc)xmlSchemaPCustomErr(pctxt, XML_SCHEMAP_INVALID_FACET_VALUE, (
xmlSchemaBasicItemPtr) fmaxinc, fmaxinc->node, "The base type's facet is 'fixed', thus the value must not "
"differ", ((void*)0));
17445 }
17446 }
17447 if (bfmaxexc) {
17448 /* maxInclusive < BASE maxExclusive */
17449 res = xmlSchemaCompareValues(fmaxinc->val, bfmaxexc->val);
17450 if (res == -2)
17451 goto internal_error;
17452 if (res != -1) {
17453 xmlSchemaDeriveFacetErr(pctxt, fmaxinc, bfmaxexc, -1, 0, 1);
17454 }
17455 }
17456 if (bfmininc) {
17457 /* maxInclusive >= BASE minInclusive */
17458 res = xmlSchemaCompareValues(fmaxinc->val, bfmininc->val);
17459 if (res == -2)
17460 goto internal_error;
17461 if (res == -1) {
17462 xmlSchemaDeriveFacetErr(pctxt, fmaxinc, bfmininc, 1, 1, 1);
17463 }
17464 }
17465 if (bfminexc) {
17466 /* maxInclusive > BASE minExclusive */
17467 res = xmlSchemaCompareValues(fmaxinc->val, bfminexc->val);
17468 if (res == -2)
17469 goto internal_error;
17470 if (res != 1) {
17471 xmlSchemaDeriveFacetErr(pctxt, fmaxinc, bfminexc, 1, 0, 1);
17472 }
17473 }
17474 }
17475 if (fmaxexc) {
17476 /*
17477 * "maxExclusive >= minExclusive"
17478 */
17479 if (fminexc) {
17480 res = xmlSchemaCompareValues(fmaxexc->val, fminexc->val);
17481 if (res == -2)
17482 goto internal_error;
17483 if (res == -1) {
17484 xmlSchemaDeriveFacetErr(pctxt, fmaxexc, fminexc, 1, 1, 0);
17485 }
17486 }
17487 /*
17488 * "maxExclusive valid restriction"
17489 */
17490 if (bfmaxexc) {
17491 /* maxExclusive <= BASE maxExclusive */
17492 res = xmlSchemaCompareValues(fmaxexc->val, bfmaxexc->val);
17493 if (res == -2)
17494 goto internal_error;
17495 if (res == 1) {
17496 xmlSchemaDeriveFacetErr(pctxt, fmaxexc, bfmaxexc, -1, 1, 1);
17497 }
17498 if ((res != 0) && (bfmaxexc->fixed)) {
17499 FACET_RESTR_FIXED_ERR(fmaxexc)xmlSchemaPCustomErr(pctxt, XML_SCHEMAP_INVALID_FACET_VALUE, (
xmlSchemaBasicItemPtr) fmaxexc, fmaxexc->node, "The base type's facet is 'fixed', thus the value must not "
"differ", ((void*)0));
17500 }
17501 }
17502 if (bfmaxinc) {
17503 /* maxExclusive <= BASE maxInclusive */
17504 res = xmlSchemaCompareValues(fmaxexc->val, bfmaxinc->val);
17505 if (res == -2)
17506 goto internal_error;
17507 if (res == 1) {
17508 xmlSchemaDeriveFacetErr(pctxt, fmaxexc, bfmaxinc, -1, 1, 1);
17509 }
17510 }
17511 if (bfmininc) {
17512 /* maxExclusive > BASE minInclusive */
17513 res = xmlSchemaCompareValues(fmaxexc->val, bfmininc->val);
17514 if (res == -2)
17515 goto internal_error;
17516 if (res != 1) {
17517 xmlSchemaDeriveFacetErr(pctxt, fmaxexc, bfmininc, 1, 0, 1);
17518 }
17519 }
17520 if (bfminexc) {
17521 /* maxExclusive > BASE minExclusive */
17522 res = xmlSchemaCompareValues(fmaxexc->val, bfminexc->val);
17523 if (res == -2)
17524 goto internal_error;
17525 if (res != 1) {
17526 xmlSchemaDeriveFacetErr(pctxt, fmaxexc, bfminexc, 1, 0, 1);
17527 }
17528 }
17529 }
17530 if (fminexc) {
17531 /*
17532 * "minExclusive < maxInclusive"
17533 */
17534 if (fmaxinc) {
17535 res = xmlSchemaCompareValues(fminexc->val, fmaxinc->val);
17536 if (res == -2)
17537 goto internal_error;
17538 if (res != -1) {
17539 xmlSchemaDeriveFacetErr(pctxt, fminexc, fmaxinc, -1, 0, 0);
17540 }
17541 }
17542 /*
17543 * "minExclusive valid restriction"
17544 */
17545 if (bfminexc) {
17546 /* minExclusive >= BASE minExclusive */
17547 res = xmlSchemaCompareValues(fminexc->val, bfminexc->val);
17548 if (res == -2)
17549 goto internal_error;
17550 if (res == -1) {
17551 xmlSchemaDeriveFacetErr(pctxt, fminexc, bfminexc, 1, 1, 1);
17552 }
17553 if ((res != 0) && (bfminexc->fixed)) {
17554 FACET_RESTR_FIXED_ERR(fminexc)xmlSchemaPCustomErr(pctxt, XML_SCHEMAP_INVALID_FACET_VALUE, (
xmlSchemaBasicItemPtr) fminexc, fminexc->node, "The base type's facet is 'fixed', thus the value must not "
"differ", ((void*)0));
17555 }
17556 }
17557 if (bfmaxinc) {
17558 /* minExclusive <= BASE maxInclusive */
17559 res = xmlSchemaCompareValues(fminexc->val, bfmaxinc->val);
17560 if (res == -2)
17561 goto internal_error;
17562 if (res == 1) {
17563 xmlSchemaDeriveFacetErr(pctxt, fminexc, bfmaxinc, -1, 1, 1);
17564 }
17565 }
17566 if (bfmininc) {
17567 /* minExclusive >= BASE minInclusive */
17568 res = xmlSchemaCompareValues(fminexc->val, bfmininc->val);
17569 if (res == -2)
17570 goto internal_error;
17571 if (res == -1) {
17572 xmlSchemaDeriveFacetErr(pctxt, fminexc, bfmininc, 1, 1, 1);
17573 }
17574 }
17575 if (bfmaxexc) {
17576 /* minExclusive < BASE maxExclusive */
17577 res = xmlSchemaCompareValues(fminexc->val, bfmaxexc->val);
17578 if (res == -2)
17579 goto internal_error;
17580 if (res != -1) {
17581 xmlSchemaDeriveFacetErr(pctxt, fminexc, bfmaxexc, -1, 0, 1);
17582 }
17583 }
17584 }
17585 if (fmininc) {
17586 /*
17587 * "minInclusive < maxExclusive"
17588 */
17589 if (fmaxexc) {
17590 res = xmlSchemaCompareValues(fmininc->val, fmaxexc->val);
17591 if (res == -2)
17592 goto internal_error;
17593 if (res != -1) {
17594 xmlSchemaDeriveFacetErr(pctxt, fmininc, fmaxexc, -1, 0, 0);
17595 }
17596 }
17597 /*
17598 * "minExclusive valid restriction"
17599 */
17600 if (bfmininc) {
17601 /* minInclusive >= BASE minInclusive */
17602 res = xmlSchemaCompareValues(fmininc->val, bfmininc->val);
17603 if (res == -2)
17604 goto internal_error;
17605 if (res == -1) {
17606 xmlSchemaDeriveFacetErr(pctxt, fmininc, bfmininc, 1, 1, 1);
17607 }
17608 if ((res != 0) && (bfmininc->fixed)) {
17609 FACET_RESTR_FIXED_ERR(fmininc)xmlSchemaPCustomErr(pctxt, XML_SCHEMAP_INVALID_FACET_VALUE, (
xmlSchemaBasicItemPtr) fmininc, fmininc->node, "The base type's facet is 'fixed', thus the value must not "
"differ", ((void*)0));
17610 }
17611 }
17612 if (bfmaxinc) {
17613 /* minInclusive <= BASE maxInclusive */
17614 res = xmlSchemaCompareValues(fmininc->val, bfmaxinc->val);
17615 if (res == -2)
17616 goto internal_error;
17617 if (res == 1) {
17618 xmlSchemaDeriveFacetErr(pctxt, fmininc, bfmaxinc, -1, 1, 1);
17619 }
17620 }
17621 if (bfminexc) {
17622 /* minInclusive > BASE minExclusive */
17623 res = xmlSchemaCompareValues(fmininc->val, bfminexc->val);
17624 if (res == -2)
17625 goto internal_error;
17626 if (res != 1)
17627 xmlSchemaDeriveFacetErr(pctxt, fmininc, bfminexc, 1, 0, 1);
17628 }
17629 if (bfmaxexc) {
17630 /* minInclusive < BASE maxExclusive */
17631 res = xmlSchemaCompareValues(fmininc->val, bfmaxexc->val);
17632 if (res == -2)
17633 goto internal_error;
17634 if (res != -1)
17635 xmlSchemaDeriveFacetErr(pctxt, fmininc, bfmaxexc, -1, 0, 1);
17636 }
17637 }
17638 if (ftotdig && bftotdig) {
17639 /*
17640 * SCC " totalDigits valid restriction"
17641 * totalDigits <= BASE totalDigits
17642 */
17643 res = xmlSchemaCompareValues(ftotdig->val, bftotdig->val);
17644 if (res == -2)
17645 goto internal_error;
17646 if (res == 1)
17647 xmlSchemaDeriveFacetErr(pctxt, ftotdig, bftotdig,
17648 -1, 1, 1);
17649 if ((res != 0) && (bftotdig->fixed)) {
17650 FACET_RESTR_FIXED_ERR(ftotdig)xmlSchemaPCustomErr(pctxt, XML_SCHEMAP_INVALID_FACET_VALUE, (
xmlSchemaBasicItemPtr) ftotdig, ftotdig->node, "The base type's facet is 'fixed', thus the value must not "
"differ", ((void*)0));
17651 }
17652 }
17653 if (ffracdig && bffracdig) {
17654 /*
17655 * SCC "fractionDigits valid restriction"
17656 * fractionDigits <= BASE fractionDigits
17657 */
17658 res = xmlSchemaCompareValues(ffracdig->val, bffracdig->val);
17659 if (res == -2)
17660 goto internal_error;
17661 if (res == 1)
17662 xmlSchemaDeriveFacetErr(pctxt, ffracdig, bffracdig,
17663 -1, 1, 1);
17664 if ((res != 0) && (bffracdig->fixed)) {
17665 FACET_RESTR_FIXED_ERR(ffracdig)xmlSchemaPCustomErr(pctxt, XML_SCHEMAP_INVALID_FACET_VALUE, (
xmlSchemaBasicItemPtr) ffracdig, ffracdig->node, "The base type's facet is 'fixed', thus the value must not "
"differ", ((void*)0));
17666 }
17667 }
17668 /*
17669 * SCC "fractionDigits less than or equal to totalDigits"
17670 */
17671 if (! ftotdig)
17672 ftotdig = bftotdig;
17673 if (! ffracdig)
17674 ffracdig = bffracdig;
17675 if (ftotdig && ffracdig) {
17676 res = xmlSchemaCompareValues(ffracdig->val, ftotdig->val);
17677 if (res == -2)
17678 goto internal_error;
17679 if (res == 1)
17680 xmlSchemaDeriveFacetErr(pctxt, ffracdig, ftotdig,
17681 -1, 1, 0);
17682 }
17683 /*
17684 * *Enumerations* won' be added here, since only the first set
17685 * of enumerations in the ancestor-or-self axis is used
17686 * for validation, plus we need to use the base type of those
17687 * enumerations for whitespace.
17688 *
17689 * *Patterns*: won't be add here, since they are ORed at
17690 * type level and ANDed at ancestor level. This will
17691 * happen during validation by walking the base axis
17692 * of the type.
17693 */
17694 for (cur = base->facetSet; cur != NULL((void*)0); cur = cur->next) {
17695 bfacet = cur->facet;
17696 /*
17697 * Special handling of enumerations and patterns.
17698 * TODO: hmm, they should not appear in the set, so remove this.
17699 */
17700 if ((bfacet->type == XML_SCHEMA_FACET_PATTERN) ||
17701 (bfacet->type == XML_SCHEMA_FACET_ENUMERATION))
17702 continue;
17703 /*
17704 * Search for a duplicate facet in the current type.
17705 */
17706 link = type->facetSet;
17707 /* err = 0; */
17708 /* fixedErr = 0; */
17709 while (link != NULL((void*)0)) {
17710 facet = link->facet;
17711 if (facet->type == bfacet->type) {
17712 switch (facet->type) {
17713 case XML_SCHEMA_FACET_WHITESPACE:
17714 /*
17715 * The whitespace must be stronger.
17716 */
17717 if (facet->whitespace < bfacet->whitespace) {
17718 FACET_RESTR_ERR(facet,xmlSchemaPCustomErr(pctxt, XML_SCHEMAP_INVALID_FACET_VALUE, (
xmlSchemaBasicItemPtr) facet, facet->node, "The 'whitespace' value has to be equal to "
"or stronger than the 'whitespace' value of " "the base type"
, ((void*)0));
17719 "The 'whitespace' value has to be equal to "xmlSchemaPCustomErr(pctxt, XML_SCHEMAP_INVALID_FACET_VALUE, (
xmlSchemaBasicItemPtr) facet, facet->node, "The 'whitespace' value has to be equal to "
"or stronger than the 'whitespace' value of " "the base type"
, ((void*)0));
17720 "or stronger than the 'whitespace' value of "xmlSchemaPCustomErr(pctxt, XML_SCHEMAP_INVALID_FACET_VALUE, (
xmlSchemaBasicItemPtr) facet, facet->node, "The 'whitespace' value has to be equal to "
"or stronger than the 'whitespace' value of " "the base type"
, ((void*)0));
17721 "the base type")xmlSchemaPCustomErr(pctxt, XML_SCHEMAP_INVALID_FACET_VALUE, (
xmlSchemaBasicItemPtr) facet, facet->node, "The 'whitespace' value has to be equal to "
"or stronger than the 'whitespace' value of " "the base type"
, ((void*)0));
17722 }
17723 if ((bfacet->fixed) &&
17724 (facet->whitespace != bfacet->whitespace)) {
17725 FACET_RESTR_FIXED_ERR(facet)xmlSchemaPCustomErr(pctxt, XML_SCHEMAP_INVALID_FACET_VALUE, (
xmlSchemaBasicItemPtr) facet, facet->node, "The base type's facet is 'fixed', thus the value must not "
"differ", ((void*)0));
17726 }
17727 break;
17728 default:
17729 break;
17730 }
17731 /* Duplicate found. */
17732 break;
17733 }
17734 link = link->next;
17735 }
17736 /*
17737 * If no duplicate was found: add the base types's facet
17738 * to the set.
17739 */
17740 if (link == NULL((void*)0)) {
17741 link = (xmlSchemaFacetLinkPtr)
17742 xmlMalloc(sizeof(xmlSchemaFacetLink));
17743 if (link == NULL((void*)0)) {
17744 xmlSchemaPErrMemory(pctxt,
17745 "deriving facets, creating a facet link", NULL((void*)0));
17746 return (-1);
17747 }
17748 link->facet = cur->facet;
17749 link->next = NULL((void*)0);
17750 if (last == NULL((void*)0))
17751 type->facetSet = link;
17752 else
17753 last->next = link;
17754 last = link;
17755 }
17756
17757 }
17758
17759 return (0);
17760internal_error:
17761 PERROR_INT("xmlSchemaDeriveAndValidateFacets",xmlSchemaInternalErr((xmlSchemaAbstractCtxtPtr) pctxt, "xmlSchemaDeriveAndValidateFacets"
, "an error occurred");
17762 "an error occurred")xmlSchemaInternalErr((xmlSchemaAbstractCtxtPtr) pctxt, "xmlSchemaDeriveAndValidateFacets"
, "an error occurred");
;
17763 return (-1);
17764}
17765
17766static int
17767xmlSchemaFinishMemberTypeDefinitionsProperty(xmlSchemaParserCtxtPtr pctxt,
17768 xmlSchemaTypePtr type)
17769{
17770 xmlSchemaTypeLinkPtr link, lastLink, prevLink, subLink, newLink;
17771 /*
17772 * The actual value is then formed by replacing any union type
17773 * definition in the `explicit members` with the members of their
17774 * {member type definitions}, in order.
17775 *
17776 * TODO: There's a bug entry at
17777 * "http://lists.w3.org/Archives/Public/www-xml-schema-comments/2005JulSep/0287.html"
17778 * which indicates that we'll keep the union types the future.
17779 */
17780 link = type->memberTypes;
17781 while (link != NULL((void*)0)) {
17782
17783 if (WXS_IS_TYPE_NOT_FIXED(link->type)(((link->type)->type != XML_SCHEMA_TYPE_BASIC) &&
(((link->type)->flags & 1 << 22) == 0))
)
17784 xmlSchemaTypeFixup(link->type, ACTXT_CAST(xmlSchemaAbstractCtxtPtr) pctxt);
17785
17786 if (WXS_IS_UNION(link->type)(link->type->flags & 1 << 7)) {
17787 subLink = xmlSchemaGetUnionSimpleTypeMemberTypes(link->type);
17788 if (subLink != NULL((void*)0)) {
17789 link->type = subLink->type;
17790 if (subLink->next != NULL((void*)0)) {
17791 lastLink = link->next;
17792 subLink = subLink->next;
17793 prevLink = link;
17794 while (subLink != NULL((void*)0)) {
17795 newLink = (xmlSchemaTypeLinkPtr)
17796 xmlMalloc(sizeof(xmlSchemaTypeLink));
17797 if (newLink == NULL((void*)0)) {
17798 xmlSchemaPErrMemory(pctxt, "allocating a type link",
17799 NULL((void*)0));
17800 return (-1);
17801 }
17802 newLink->type = subLink->type;
17803 prevLink->next = newLink;
17804 prevLink = newLink;
17805 newLink->next = lastLink;
17806
17807 subLink = subLink->next;
17808 }
17809 }
17810 }
17811 }
17812 link = link->next;
17813 }
17814 return (0);
17815}
17816
17817static void
17818xmlSchemaTypeFixupOptimFacets(xmlSchemaTypePtr type)
17819{
17820 int has = 0, needVal = 0, normVal = 0;
17821
17822 has = (type->baseType->flags & XML_SCHEMAS_TYPE_HAS_FACETS1 << 27) ? 1 : 0;
17823 if (has) {
17824 needVal = (type->baseType->flags &
17825 XML_SCHEMAS_TYPE_FACETSNEEDVALUE1 << 21) ? 1 : 0;
17826 normVal = (type->baseType->flags &
17827 XML_SCHEMAS_TYPE_NORMVALUENEEDED1 << 28) ? 1 : 0;
17828 }
17829 if (type->facets != NULL((void*)0)) {
17830 xmlSchemaFacetPtr fac;
17831
17832 for (fac = type->facets; fac != NULL((void*)0); fac = fac->next) {
17833 switch (fac->type) {
17834 case XML_SCHEMA_FACET_WHITESPACE:
17835 break;
17836 case XML_SCHEMA_FACET_PATTERN:
17837 normVal = 1;
17838 has = 1;
17839 break;
17840 case XML_SCHEMA_FACET_ENUMERATION:
17841 needVal = 1;
17842 normVal = 1;
17843 has = 1;
17844 break;
17845 default:
17846 has = 1;
17847 break;
17848 }
17849 }
17850 }
17851 if (normVal)
17852 type->flags |= XML_SCHEMAS_TYPE_NORMVALUENEEDED1 << 28;
17853 if (needVal)
17854 type->flags |= XML_SCHEMAS_TYPE_FACETSNEEDVALUE1 << 21;
17855 if (has)
17856 type->flags |= XML_SCHEMAS_TYPE_HAS_FACETS1 << 27;
17857
17858 if (has && (! needVal) && WXS_IS_ATOMIC(type)(type->flags & 1 << 8)) {
17859 xmlSchemaTypePtr prim = xmlSchemaGetPrimitiveType(type);
17860 /*
17861 * OPTIMIZE VAL TODO: Some facets need a computed value.
17862 */
17863 if ((prim->builtInType != XML_SCHEMAS_ANYSIMPLETYPE) &&
17864 (prim->builtInType != XML_SCHEMAS_STRING)) {
17865 type->flags |= XML_SCHEMAS_TYPE_FACETSNEEDVALUE1 << 21;
17866 }
17867 }
17868}
17869
17870static int
17871xmlSchemaTypeFixupWhitespace(xmlSchemaTypePtr type)
17872{
17873
17874
17875 /*
17876 * Evaluate the whitespace-facet value.
17877 */
17878 if (WXS_IS_LIST(type)(type->flags & 1 << 6)) {
17879 type->flags |= XML_SCHEMAS_TYPE_WHITESPACE_COLLAPSE1 << 26;
17880 return (0);
17881 } else if (WXS_IS_UNION(type)(type->flags & 1 << 7))
17882 return (0);
17883
17884 if (type->facetSet != NULL((void*)0)) {
17885 xmlSchemaFacetLinkPtr lin;
17886
17887 for (lin = type->facetSet; lin != NULL((void*)0); lin = lin->next) {
17888 if (lin->facet->type == XML_SCHEMA_FACET_WHITESPACE) {
17889 switch (lin->facet->whitespace) {
17890 case XML_SCHEMAS_FACET_PRESERVE1:
17891 type->flags |= XML_SCHEMAS_TYPE_WHITESPACE_PRESERVE1 << 24;
17892 break;
17893 case XML_SCHEMAS_FACET_REPLACE2:
17894 type->flags |= XML_SCHEMAS_TYPE_WHITESPACE_REPLACE1 << 25;
17895 break;
17896 case XML_SCHEMAS_FACET_COLLAPSE3:
17897 type->flags |= XML_SCHEMAS_TYPE_WHITESPACE_COLLAPSE1 << 26;
17898 break;
17899 default:
17900 return (-1);
17901 }
17902 return (0);
17903 }
17904 }
17905 }
17906 /*
17907 * For all `atomic` datatypes other than string (and types `derived`
17908 * by `restriction` from it) the value of whiteSpace is fixed to
17909 * collapse
17910 */
17911 {
17912 xmlSchemaTypePtr anc;
17913
17914 for (anc = type->baseType; anc != NULL((void*)0) &&
17915 anc->builtInType != XML_SCHEMAS_ANYTYPE;
17916 anc = anc->baseType) {
17917
17918 if (anc->type == XML_SCHEMA_TYPE_BASIC) {
17919 if (anc->builtInType == XML_SCHEMAS_NORMSTRING) {
17920 type->flags |= XML_SCHEMAS_TYPE_WHITESPACE_REPLACE1 << 25;
17921
17922 } else if ((anc->builtInType == XML_SCHEMAS_STRING) ||
17923 (anc->builtInType == XML_SCHEMAS_ANYSIMPLETYPE)) {
17924 type->flags |= XML_SCHEMAS_TYPE_WHITESPACE_PRESERVE1 << 24;
17925
17926 } else
17927 type->flags |= XML_SCHEMAS_TYPE_WHITESPACE_COLLAPSE1 << 26;
17928 break;
17929 }
17930 }
17931 }
17932 return (0);
17933}
17934
17935static int
17936xmlSchemaFixupSimpleTypeStageOne(xmlSchemaParserCtxtPtr pctxt,
17937 xmlSchemaTypePtr type)
17938{
17939 if (type->type != XML_SCHEMA_TYPE_SIMPLE)
17940 return(0);
17941 if (! WXS_IS_TYPE_NOT_FIXED_1(type)(((type)->type != XML_SCHEMA_TYPE_BASIC) && (((type
)->flags & 1 << 29) == 0))
)
17942 return(0);
17943 type->flags |= XML_SCHEMAS_TYPE_FIXUP_11 << 29;
17944
17945 if (WXS_IS_LIST(type)(type->flags & 1 << 6)) {
17946 /*
17947 * Corresponds to <simpleType><list>...
17948 */
17949 if (type->subtypes == NULL((void*)0)) {
17950 /*
17951 * This one is really needed, so get out.
17952 */
17953 PERROR_INT("xmlSchemaFixupSimpleTypeStageOne",xmlSchemaInternalErr((xmlSchemaAbstractCtxtPtr) pctxt, "xmlSchemaFixupSimpleTypeStageOne"
, "list type has no item-type assigned");
17954 "list type has no item-type assigned")xmlSchemaInternalErr((xmlSchemaAbstractCtxtPtr) pctxt, "xmlSchemaFixupSimpleTypeStageOne"
, "list type has no item-type assigned");
;
17955 return(-1);
17956 }
17957 } else if (WXS_IS_UNION(type)(type->flags & 1 << 7)) {
17958 /*
17959 * Corresponds to <simpleType><union>...
17960 */
17961 if (type->memberTypes == NULL((void*)0)) {
17962 /*
17963 * This one is really needed, so get out.
17964 */
17965 PERROR_INT("xmlSchemaFixupSimpleTypeStageOne",xmlSchemaInternalErr((xmlSchemaAbstractCtxtPtr) pctxt, "xmlSchemaFixupSimpleTypeStageOne"
, "union type has no member-types assigned");
17966 "union type has no member-types assigned")xmlSchemaInternalErr((xmlSchemaAbstractCtxtPtr) pctxt, "xmlSchemaFixupSimpleTypeStageOne"
, "union type has no member-types assigned");
;
17967 return(-1);
17968 }
17969 } else {
17970 /*
17971 * Corresponds to <simpleType><restriction>...
17972 */
17973 if (type->baseType == NULL((void*)0)) {
17974 PERROR_INT("xmlSchemaFixupSimpleTypeStageOne",xmlSchemaInternalErr((xmlSchemaAbstractCtxtPtr) pctxt, "xmlSchemaFixupSimpleTypeStageOne"
, "type has no base-type assigned");
17975 "type has no base-type assigned")xmlSchemaInternalErr((xmlSchemaAbstractCtxtPtr) pctxt, "xmlSchemaFixupSimpleTypeStageOne"
, "type has no base-type assigned");
;
17976 return(-1);
17977 }
17978 if (WXS_IS_TYPE_NOT_FIXED_1(type->baseType)(((type->baseType)->type != XML_SCHEMA_TYPE_BASIC) &&
(((type->baseType)->flags & 1 << 29) == 0))
)
17979 if (xmlSchemaFixupSimpleTypeStageOne(pctxt, type->baseType) == -1)
17980 return(-1);
17981 /*
17982 * Variety
17983 * If the <restriction> alternative is chosen, then the
17984 * {variety} of the {base type definition}.
17985 */
17986 if (WXS_IS_ATOMIC(type->baseType)(type->baseType->flags & 1 << 8))
17987 type->flags |= XML_SCHEMAS_TYPE_VARIETY_ATOMIC1 << 8;
17988 else if (WXS_IS_LIST(type->baseType)(type->baseType->flags & 1 << 6)) {
17989 type->flags |= XML_SCHEMAS_TYPE_VARIETY_LIST1 << 6;
17990 /*
17991 * Inherit the itemType.
17992 */
17993 type->subtypes = type->baseType->subtypes;
17994 } else if (WXS_IS_UNION(type->baseType)(type->baseType->flags & 1 << 7)) {
17995 type->flags |= XML_SCHEMAS_TYPE_VARIETY_UNION1 << 7;
17996 /*
17997 * NOTE that we won't assign the memberTypes of the base,
17998 * since this will make trouble when freeing them; we will
17999 * use a lookup function to access them instead.
18000 */
18001 }
18002 }
18003 return(0);
18004}
18005
18006/*
18007* 3.14.6 Constraints on Simple Type Definition Schema Components
18008*/
18009static int
18010xmlSchemaFixupSimpleTypeStageTwo(xmlSchemaParserCtxtPtr pctxt,
18011 xmlSchemaTypePtr type)
18012{
18013 int res, olderrs = pctxt->nberrors;
18014
18015 if (type->type != XML_SCHEMA_TYPE_SIMPLE)
18016 return(-1);
18017
18018 if (! WXS_IS_TYPE_NOT_FIXED(type)(((type)->type != XML_SCHEMA_TYPE_BASIC) && (((type
)->flags & 1 << 22) == 0))
)
18019 return(0);
18020
18021 type->flags |= XML_SCHEMAS_TYPE_INTERNAL_RESOLVED1 << 22;
18022 type->contentType = XML_SCHEMA_CONTENT_SIMPLE;
18023
18024 if (type->baseType == NULL((void*)0)) {
18025 PERROR_INT("xmlSchemaFixupSimpleTypeStageTwo",xmlSchemaInternalErr((xmlSchemaAbstractCtxtPtr) pctxt, "xmlSchemaFixupSimpleTypeStageTwo"
, "missing baseType");
18026 "missing baseType")xmlSchemaInternalErr((xmlSchemaAbstractCtxtPtr) pctxt, "xmlSchemaFixupSimpleTypeStageTwo"
, "missing baseType");
;
18027 goto exit_failure;
18028 }
18029 if (WXS_IS_TYPE_NOT_FIXED(type->baseType)(((type->baseType)->type != XML_SCHEMA_TYPE_BASIC) &&
(((type->baseType)->flags & 1 << 22) == 0))
)
18030 xmlSchemaTypeFixup(type->baseType, ACTXT_CAST(xmlSchemaAbstractCtxtPtr) pctxt);
18031 /*
18032 * If a member type of a union is a union itself, we need to substitute
18033 * that member type for its member types.
18034 * NOTE that this might change in WXS 1.1; i.e. we will keep the union
18035 * types in WXS 1.1.
18036 */
18037 if ((type->memberTypes != NULL((void*)0)) &&
18038 (xmlSchemaFinishMemberTypeDefinitionsProperty(pctxt, type) == -1))
18039 return(-1);
18040 /*
18041 * SPEC src-simple-type 1
18042 * "The corresponding simple type definition, if any, must satisfy
18043 * the conditions set out in Constraints on Simple Type Definition
18044 * Schema Components ($3.14.6)."
18045 */
18046 /*
18047 * Schema Component Constraint: Simple Type Definition Properties Correct
18048 * (st-props-correct)
18049 */
18050 res = xmlSchemaCheckSTPropsCorrect(pctxt, type);
18051 HFAILUREif (res == -1) goto exit_failure; HERRORif (res != 0) goto exit_error;
18052 /*
18053 * Schema Component Constraint: Derivation Valid (Restriction, Simple)
18054 * (cos-st-restricts)
18055 */
18056 res = xmlSchemaCheckCOSSTRestricts(pctxt, type);
18057 HFAILUREif (res == -1) goto exit_failure; HERRORif (res != 0) goto exit_error;
18058 /*
18059 * TODO: Removed the error report, since it got annoying to get an
18060 * extra error report, if anything failed until now.
18061 * Enable this if needed.
18062 *
18063 * xmlSchemaPErr(ctxt, type->node,
18064 * XML_SCHEMAP_SRC_SIMPLE_TYPE_1,
18065 * "Simple type '%s' does not satisfy the constraints "
18066 * "on simple type definitions.\n",
18067 * type->name, NULL);
18068 */
18069 /*
18070 * Schema Component Constraint: Simple Type Restriction (Facets)
18071 * (st-restrict-facets)
18072 */
18073 res = xmlSchemaCheckFacetValues(type, pctxt);
18074 HFAILUREif (res == -1) goto exit_failure; HERRORif (res != 0) goto exit_error;
18075 if ((type->facetSet != NULL((void*)0)) ||
18076 (type->baseType->facetSet != NULL((void*)0))) {
18077 res = xmlSchemaDeriveAndValidateFacets(pctxt, type);
18078 HFAILUREif (res == -1) goto exit_failure; HERRORif (res != 0) goto exit_error;
18079 }
18080 /*
18081 * Whitespace value.
18082 */
18083 res = xmlSchemaTypeFixupWhitespace(type);
18084 HFAILUREif (res == -1) goto exit_failure; HERRORif (res != 0) goto exit_error;
18085 xmlSchemaTypeFixupOptimFacets(type);
18086
18087exit_error:
18088 if (olderrs != pctxt->nberrors)
18089 return(pctxt->err);
18090 return(0);
18091
18092exit_failure:
18093 return(-1);
18094}
18095
18096static int
18097xmlSchemaFixupComplexType(xmlSchemaParserCtxtPtr pctxt,
18098 xmlSchemaTypePtr type)
18099{
18100 int res = 0, olderrs = pctxt->nberrors;
18101 xmlSchemaTypePtr baseType = type->baseType;
18102
18103 if (! WXS_IS_TYPE_NOT_FIXED(type)(((type)->type != XML_SCHEMA_TYPE_BASIC) && (((type
)->flags & 1 << 22) == 0))
)
18104 return(0);
18105 type->flags |= XML_SCHEMAS_TYPE_INTERNAL_RESOLVED1 << 22;
18106 if (baseType == NULL((void*)0)) {
18107 PERROR_INT("xmlSchemaFixupComplexType",xmlSchemaInternalErr((xmlSchemaAbstractCtxtPtr) pctxt, "xmlSchemaFixupComplexType"
, "missing baseType");
18108 "missing baseType")xmlSchemaInternalErr((xmlSchemaAbstractCtxtPtr) pctxt, "xmlSchemaFixupComplexType"
, "missing baseType");
;
18109 goto exit_failure;
18110 }
18111 /*
18112 * Fixup the base type.
18113 */
18114 if (WXS_IS_TYPE_NOT_FIXED(baseType)(((baseType)->type != XML_SCHEMA_TYPE_BASIC) && ((
(baseType)->flags & 1 << 22) == 0))
)
18115 xmlSchemaTypeFixup(baseType, ACTXT_CAST(xmlSchemaAbstractCtxtPtr) pctxt);
18116 if (baseType->flags & XML_SCHEMAS_TYPE_INTERNAL_INVALID1 << 23) {
18117 /*
18118 * Skip fixup if the base type is invalid.
18119 * TODO: Generate a warning!
18120 */
18121 return(0);
18122 }
18123 /*
18124 * This basically checks if the base type can be derived.
18125 */
18126 res = xmlSchemaCheckSRCCT(pctxt, type);
18127 HFAILUREif (res == -1) goto exit_failure; HERRORif (res != 0) goto exit_error;
18128 /*
18129 * Fixup the content type.
18130 */
18131 if (type->contentType == XML_SCHEMA_CONTENT_SIMPLE) {
18132 /*
18133 * Corresponds to <complexType><simpleContent>...
18134 */
18135 if ((WXS_IS_COMPLEX(baseType)(((baseType)->type == XML_SCHEMA_TYPE_COMPLEX) || ((baseType
)->builtInType == XML_SCHEMAS_ANYTYPE))
) &&
18136 (baseType->contentTypeDef != NULL((void*)0)) &&
18137 (WXS_IS_RESTRICTION(type)((type)->flags & 1 << 2))) {
18138 xmlSchemaTypePtr contentBase, content;
18139#ifdef ENABLE_NAMED_LOCALS
18140 char buf[30];
18141 const xmlChar *tmpname;
18142#endif
18143 /*
18144 * SPEC (1) If <restriction> + base type is <complexType>,
18145 * "whose own {content type} is a simple type..."
18146 */
18147 if (type->contentTypeDef != NULL((void*)0)) {
18148 /*
18149 * SPEC (1.1) "the simple type definition corresponding to the
18150 * <simpleType> among the [children] of <restriction> if there
18151 * is one;"
18152 * Note that this "<simpleType> among the [children]" was put
18153 * into ->contentTypeDef during parsing.
18154 */
18155 contentBase = type->contentTypeDef;
18156 type->contentTypeDef = NULL((void*)0);
18157 } else {
18158 /*
18159 * (1.2) "...otherwise (<restriction> has no <simpleType>
18160 * among its [children]), the simple type definition which
18161 * is the {content type} of the ... base type."
18162 */
18163 contentBase = baseType->contentTypeDef;
18164 }
18165 /*
18166 * SPEC
18167 * "... a simple type definition which restricts the simple
18168 * type definition identified in clause 1.1 or clause 1.2
18169 * with a set of facet components"
18170 *
18171 * Create the anonymous simple type, which will be the content
18172 * type of the complex type.
18173 */
18174#ifdef ENABLE_NAMED_LOCALS
18175 snprintf(buf, 29, "#scST%d", ++(pctxt->counter));
18176 tmpname = xmlDictLookup(pctxt->dict, BAD_CAST(xmlChar *) buf, -1);
18177 content = xmlSchemaAddType(pctxt, pctxt->schema,
18178 XML_SCHEMA_TYPE_SIMPLE, tmpname, type->targetNamespace,
18179 type->node, 0);
18180#else
18181 content = xmlSchemaAddType(pctxt, pctxt->schema,
18182 XML_SCHEMA_TYPE_SIMPLE, NULL((void*)0), type->targetNamespace,
18183 type->node, 0);
18184#endif
18185 if (content == NULL((void*)0))
18186 goto exit_failure;
18187 /*
18188 * We will use the same node as for the <complexType>
18189 * to have it somehow anchored in the schema doc.
18190 */
18191 content->type = XML_SCHEMA_TYPE_SIMPLE;
18192 content->baseType = contentBase;
18193 /*
18194 * Move the facets, previously anchored on the
18195 * complexType during parsing.
18196 */
18197 content->facets = type->facets;
18198 type->facets = NULL((void*)0);
18199 content->facetSet = type->facetSet;
18200 type->facetSet = NULL((void*)0);
18201
18202 type->contentTypeDef = content;
18203 if (WXS_IS_TYPE_NOT_FIXED(contentBase)(((contentBase)->type != XML_SCHEMA_TYPE_BASIC) &&
(((contentBase)->flags & 1 << 22) == 0))
)
18204 xmlSchemaTypeFixup(contentBase, ACTXT_CAST(xmlSchemaAbstractCtxtPtr) pctxt);
18205 /*
18206 * Fixup the newly created type. We don't need to check
18207 * for circularity here.
18208 */
18209 res = xmlSchemaFixupSimpleTypeStageOne(pctxt, content);
18210 HFAILUREif (res == -1) goto exit_failure; HERRORif (res != 0) goto exit_error;
18211 res = xmlSchemaFixupSimpleTypeStageTwo(pctxt, content);
18212 HFAILUREif (res == -1) goto exit_failure; HERRORif (res != 0) goto exit_error;
18213
18214 } else if ((WXS_IS_COMPLEX(baseType)(((baseType)->type == XML_SCHEMA_TYPE_COMPLEX) || ((baseType
)->builtInType == XML_SCHEMAS_ANYTYPE))
) &&
18215 (baseType->contentType == XML_SCHEMA_CONTENT_MIXED) &&
18216 (WXS_IS_RESTRICTION(type)((type)->flags & 1 << 2))) {
18217 /*
18218 * SPEC (2) If <restriction> + base is a mixed <complexType> with
18219 * an emptiable particle, then a simple type definition which
18220 * restricts the <restriction>'s <simpleType> child.
18221 */
18222 if ((type->contentTypeDef == NULL((void*)0)) ||
18223 (type->contentTypeDef->baseType == NULL((void*)0))) {
18224 /*
18225 * TODO: Check if this ever happens.
18226 */
18227 xmlSchemaPCustomErr(pctxt,
18228 XML_SCHEMAP_INTERNAL,
18229 WXS_BASIC_CAST(xmlSchemaBasicItemPtr) type, NULL((void*)0),
18230 "Internal error: xmlSchemaTypeFixup, "
18231 "complex type '%s': the <simpleContent><restriction> "
18232 "is missing a <simpleType> child, but was not caught "
18233 "by xmlSchemaCheckSRCCT()", type->name);
18234 goto exit_failure;
18235 }
18236 } else if ((WXS_IS_COMPLEX(baseType)(((baseType)->type == XML_SCHEMA_TYPE_COMPLEX) || ((baseType
)->builtInType == XML_SCHEMAS_ANYTYPE))
) && WXS_IS_EXTENSION(type)((type)->flags & 1 << 1)) {
18237 /*
18238 * SPEC (3) If <extension> + base is <complexType> with
18239 * <simpleType> content, "...then the {content type} of that
18240 * complex type definition"
18241 */
18242 if (baseType->contentTypeDef == NULL((void*)0)) {
18243 /*
18244 * TODO: Check if this ever happens. xmlSchemaCheckSRCCT
18245 * should have caught this already.
18246 */
18247 xmlSchemaPCustomErr(pctxt,
18248 XML_SCHEMAP_INTERNAL,
18249 WXS_BASIC_CAST(xmlSchemaBasicItemPtr) type, NULL((void*)0),
18250 "Internal error: xmlSchemaTypeFixup, "
18251 "complex type '%s': the <extension>ed base type is "
18252 "a complex type with no simple content type",
18253 type->name);
18254 goto exit_failure;
18255 }
18256 type->contentTypeDef = baseType->contentTypeDef;
18257 } else if ((WXS_IS_SIMPLE(baseType)((baseType->type == XML_SCHEMA_TYPE_SIMPLE) || ((baseType->
type == XML_SCHEMA_TYPE_BASIC) && (baseType->builtInType
!= XML_SCHEMAS_ANYTYPE)))
) && WXS_IS_EXTENSION(type)((type)->flags & 1 << 1)) {
18258 /*
18259 * SPEC (4) <extension> + base is <simpleType>
18260 * "... then that simple type definition"
18261 */
18262 type->contentTypeDef = baseType;
18263 } else {
18264 /*
18265 * TODO: Check if this ever happens.
18266 */
18267 xmlSchemaPCustomErr(pctxt,
18268 XML_SCHEMAP_INTERNAL,
18269 WXS_BASIC_CAST(xmlSchemaBasicItemPtr) type, NULL((void*)0),
18270 "Internal error: xmlSchemaTypeFixup, "
18271 "complex type '%s' with <simpleContent>: unhandled "
18272 "derivation case", type->name);
18273 goto exit_failure;
18274 }
18275 } else {
18276 int dummySequence = 0;
18277 xmlSchemaParticlePtr particle =
18278 (xmlSchemaParticlePtr) type->subtypes;
18279 /*
18280 * Corresponds to <complexType><complexContent>...
18281 *
18282 * NOTE that the effective mixed was already set during parsing of
18283 * <complexType> and <complexContent>; its flag value is
18284 * XML_SCHEMAS_TYPE_MIXED.
18285 *
18286 * Compute the "effective content":
18287 * (2.1.1) + (2.1.2) + (2.1.3)
18288 */
18289 if ((particle == NULL((void*)0)) ||
18290 ((particle->type == XML_SCHEMA_TYPE_PARTICLE) &&
18291 ((particle->children->type == XML_SCHEMA_TYPE_ALL) ||
18292 (particle->children->type == XML_SCHEMA_TYPE_SEQUENCE) ||
18293 ((particle->children->type == XML_SCHEMA_TYPE_CHOICE) &&
18294 (particle->minOccurs == 0))) &&
18295 ( ((xmlSchemaTreeItemPtr) particle->children)->children == NULL((void*)0)))) {
18296 if (type->flags & XML_SCHEMAS_TYPE_MIXED1 << 0) {
18297 /*
18298 * SPEC (2.1.4) "If the `effective mixed` is true, then
18299 * a particle whose properties are as follows:..."
18300 *
18301 * Empty sequence model group with
18302 * minOccurs/maxOccurs = 1 (i.e. a "particle emptiable").
18303 * NOTE that we sill assign it the <complexType> node to
18304 * somehow anchor it in the doc.
18305 */
18306 if ((particle == NULL((void*)0)) ||
18307 (particle->children->type != XML_SCHEMA_TYPE_SEQUENCE)) {
18308 /*
18309 * Create the particle.
18310 */
18311 particle = xmlSchemaAddParticle(pctxt,
18312 type->node, 1, 1);
18313 if (particle == NULL((void*)0))
18314 goto exit_failure;
18315 /*
18316 * Create the model group.
18317 */ /* URGENT TODO: avoid adding to pending items. */
18318 particle->children = (xmlSchemaTreeItemPtr)
18319 xmlSchemaAddModelGroup(pctxt, pctxt->schema,
18320 XML_SCHEMA_TYPE_SEQUENCE, type->node);
18321 if (particle->children == NULL((void*)0))
18322 goto exit_failure;
18323
18324 type->subtypes = (xmlSchemaTypePtr) particle;
18325 }
18326 dummySequence = 1;
18327 type->contentType = XML_SCHEMA_CONTENT_ELEMENTS;
18328 } else {
18329 /*
18330 * SPEC (2.1.5) "otherwise empty"
18331 */
18332 type->contentType = XML_SCHEMA_CONTENT_EMPTY;
18333 }
18334 } else {
18335 /*
18336 * SPEC (2.2) "otherwise the particle corresponding to the
18337 * <all>, <choice>, <group> or <sequence> among the
18338 * [children]."
18339 */
18340 type->contentType = XML_SCHEMA_CONTENT_ELEMENTS;
18341 }
18342 /*
18343 * Compute the "content type".
18344 */
18345 if (WXS_IS_RESTRICTION(type)((type)->flags & 1 << 2)) {
18346 /*
18347 * SPEC (3.1) "If <restriction>..."
18348 * (3.1.1) + (3.1.2) */
18349 if (type->contentType != XML_SCHEMA_CONTENT_EMPTY) {
18350 if (type->flags & XML_SCHEMAS_TYPE_MIXED1 << 0)
18351 type->contentType = XML_SCHEMA_CONTENT_MIXED;
18352 }
18353 } else {
18354 /*
18355 * SPEC (3.2) "If <extension>..."
18356 */
18357 if (type->contentType == XML_SCHEMA_CONTENT_EMPTY) {
18358 /*
18359 * SPEC (3.2.1)
18360 * "If the `effective content` is empty, then the
18361 * {content type} of the [...] base ..."
18362 */
18363 type->contentType = baseType->contentType;
18364 type->subtypes = baseType->subtypes;
18365 /*
18366 * Fixes bug #347316:
18367 * This is the case when the base type has a simple
18368 * type definition as content.
18369 */
18370 type->contentTypeDef = baseType->contentTypeDef;
18371 /*
18372 * NOTE that the effective mixed is ignored here.
18373 */
18374 } else if (baseType->contentType == XML_SCHEMA_CONTENT_EMPTY) {
18375 /*
18376 * SPEC (3.2.2)
18377 */
18378 if (type->flags & XML_SCHEMAS_TYPE_MIXED1 << 0)
18379 type->contentType = XML_SCHEMA_CONTENT_MIXED;
18380 } else {
18381 /*
18382 * SPEC (3.2.3)
18383 */
18384 if (type->flags & XML_SCHEMAS_TYPE_MIXED1 << 0)
18385 type->contentType = XML_SCHEMA_CONTENT_MIXED;
18386 /*
18387 * "A model group whose {compositor} is sequence and whose
18388 * {particles} are..."
18389 */
18390 if ((WXS_TYPE_PARTICLE(type)(xmlSchemaParticlePtr) (type)->subtypes != NULL((void*)0)) &&
18391 (WXS_TYPE_PARTICLE_TERM(type)((xmlSchemaParticlePtr) ((xmlSchemaParticlePtr) (type)->subtypes
))->children
!= NULL((void*)0)) &&
18392 ((WXS_TYPE_PARTICLE_TERM(type)((xmlSchemaParticlePtr) ((xmlSchemaParticlePtr) (type)->subtypes
))->children
)->type ==
18393 XML_SCHEMA_TYPE_ALL))
18394 {
18395 /*
18396 * SPEC cos-all-limited (1)
18397 */
18398 xmlSchemaCustomErr(ACTXT_CAST(xmlSchemaAbstractCtxtPtr) pctxt,
18399 /* TODO: error code */
18400 XML_SCHEMAP_COS_ALL_LIMITED,
18401 WXS_ITEM_NODE(type)xmlSchemaGetComponentNode((xmlSchemaBasicItemPtr) (type)), NULL((void*)0),
18402 "The type has an 'all' model group in its "
18403 "{content type} and thus cannot be derived from "
18404 "a non-empty type, since this would produce a "
18405 "'sequence' model group containing the 'all' "
18406 "model group; 'all' model groups are not "
18407 "allowed to appear inside other model groups",
18408 NULL((void*)0), NULL((void*)0));
18409
18410 } else if ((WXS_TYPE_PARTICLE(baseType)(xmlSchemaParticlePtr) (baseType)->subtypes != NULL((void*)0)) &&
18411 (WXS_TYPE_PARTICLE_TERM(baseType)((xmlSchemaParticlePtr) ((xmlSchemaParticlePtr) (baseType)->
subtypes))->children
!= NULL((void*)0)) &&
18412 ((WXS_TYPE_PARTICLE_TERM(baseType)((xmlSchemaParticlePtr) ((xmlSchemaParticlePtr) (baseType)->
subtypes))->children
)->type ==
18413 XML_SCHEMA_TYPE_ALL))
18414 {
18415 /*
18416 * SPEC cos-all-limited (1)
18417 */
18418 xmlSchemaCustomErr(ACTXT_CAST(xmlSchemaAbstractCtxtPtr) pctxt,
18419 /* TODO: error code */
18420 XML_SCHEMAP_COS_ALL_LIMITED,
18421 WXS_ITEM_NODE(type)xmlSchemaGetComponentNode((xmlSchemaBasicItemPtr) (type)), NULL((void*)0),
18422 "A type cannot be derived by extension from a type "
18423 "which has an 'all' model group in its "
18424 "{content type}, since this would produce a "
18425 "'sequence' model group containing the 'all' "
18426 "model group; 'all' model groups are not "
18427 "allowed to appear inside other model groups",
18428 NULL((void*)0), NULL((void*)0));
18429
18430 } else if ((!dummySequence) && (baseType->subtypes != NULL((void*)0))) {
18431 xmlSchemaTreeItemPtr effectiveContent =
18432 (xmlSchemaTreeItemPtr) type->subtypes;
18433 /*
18434 * Create the particle.
18435 */
18436 particle = xmlSchemaAddParticle(pctxt,
18437 type->node, 1, 1);
18438 if (particle == NULL((void*)0))
18439 goto exit_failure;
18440 /*
18441 * Create the "sequence" model group.
18442 */
18443 particle->children = (xmlSchemaTreeItemPtr)
18444 xmlSchemaAddModelGroup(pctxt, pctxt->schema,
18445 XML_SCHEMA_TYPE_SEQUENCE, type->node);
18446 if (particle->children == NULL((void*)0))
18447 goto exit_failure;
18448 WXS_TYPE_CONTENTTYPE(type)(type)->subtypes = (xmlSchemaTypePtr) particle;
18449 /*
18450 * SPEC "the particle of the {content type} of
18451 * the ... base ..."
18452 * Create a duplicate of the base type's particle
18453 * and assign its "term" to it.
18454 */
18455 particle->children->children =
18456 (xmlSchemaTreeItemPtr) xmlSchemaAddParticle(pctxt,
18457 type->node,
18458 ((xmlSchemaParticlePtr) baseType->subtypes)->minOccurs,
18459 ((xmlSchemaParticlePtr) baseType->subtypes)->maxOccurs);
18460 if (particle->children->children == NULL((void*)0))
18461 goto exit_failure;
18462 particle = (xmlSchemaParticlePtr)
18463 particle->children->children;
18464 particle->children =
18465 ((xmlSchemaParticlePtr) baseType->subtypes)->children;
18466 /*
18467 * SPEC "followed by the `effective content`."
18468 */
18469 particle->next = effectiveContent;
18470 /*
18471 * This all will result in:
18472 * new-particle
18473 * --> new-sequence(
18474 * new-particle
18475 * --> base-model,
18476 * this-particle
18477 * --> this-model
18478 * )
18479 */
18480 } else {
18481 /*
18482 * This is the case when there is already an empty
18483 * <sequence> with minOccurs==maxOccurs==1.
18484 * Just add the base types's content type.
18485 * NOTE that, although we miss to add an intermediate
18486 * <sequence>, this should produce no difference to
18487 * neither the regex compilation of the content model,
18488 * nor to the complex type constraints.
18489 */
18490 particle->children->children =
18491 (xmlSchemaTreeItemPtr) baseType->subtypes;
18492 }
18493 }
18494 }
18495 }
18496 /*
18497 * Now fixup attribute uses:
18498 * - expand attr. group references
18499 * - intersect attribute wildcards
18500 * - inherit attribute uses of the base type
18501 * - inherit or union attr. wildcards if extending
18502 * - apply attr. use prohibitions if restricting
18503 */
18504 res = xmlSchemaFixupTypeAttributeUses(pctxt, type);
18505 HFAILUREif (res == -1) goto exit_failure; HERRORif (res != 0) goto exit_error;
18506 /*
18507 * Apply the complex type component constraints; this will not
18508 * check attributes, since this is done in
18509 * xmlSchemaFixupTypeAttributeUses().
18510 */
18511 res = xmlSchemaCheckCTComponent(pctxt, type);
18512 HFAILUREif (res == -1) goto exit_failure; HERRORif (res != 0) goto exit_error;
18513
18514 if (olderrs != pctxt->nberrors)
18515 return(pctxt->err);
18516 else
18517 return(0);
18518
18519exit_error:
18520 type->flags |= XML_SCHEMAS_TYPE_INTERNAL_INVALID1 << 23;
18521 return(pctxt->err);
18522
18523exit_failure:
18524 type->flags |= XML_SCHEMAS_TYPE_INTERNAL_INVALID1 << 23;
18525 return(-1);
18526}
18527
18528
18529/**
18530 * xmlSchemaTypeFixup:
18531 * @typeDecl: the schema type definition
18532 * @ctxt: the schema parser context
18533 *
18534 * Fixes the content model of the type.
18535 * URGENT TODO: We need an int result!
18536 */
18537static int
18538xmlSchemaTypeFixup(xmlSchemaTypePtr type,
18539 xmlSchemaAbstractCtxtPtr actxt)
18540{
18541 if (type == NULL((void*)0))
18542 return(0);
18543 if (actxt->type != XML_SCHEMA_CTXT_PARSER1) {
18544 AERROR_INT("xmlSchemaTypeFixup",xmlSchemaInternalErr(actxt, "xmlSchemaTypeFixup", "this function needs a parser context"
);
18545 "this function needs a parser context")xmlSchemaInternalErr(actxt, "xmlSchemaTypeFixup", "this function needs a parser context"
);
;
18546 return(-1);
18547 }
18548 if (! WXS_IS_TYPE_NOT_FIXED(type)(((type)->type != XML_SCHEMA_TYPE_BASIC) && (((type
)->flags & 1 << 22) == 0))
)
18549 return(0);
18550 if (type->type == XML_SCHEMA_TYPE_COMPLEX)
18551 return(xmlSchemaFixupComplexType(PCTXT_CAST(xmlSchemaParserCtxtPtr) actxt, type));
18552 else if (type->type == XML_SCHEMA_TYPE_SIMPLE)
18553 return(xmlSchemaFixupSimpleTypeStageTwo(PCTXT_CAST(xmlSchemaParserCtxtPtr) actxt, type));
18554 return(0);
18555}
18556
18557/**
18558 * xmlSchemaCheckFacet:
18559 * @facet: the facet
18560 * @typeDecl: the schema type definition
18561 * @pctxt: the schema parser context or NULL
18562 * @name: the optional name of the type
18563 *
18564 * Checks and computes the values of facets.
18565 *
18566 * Returns 0 if valid, a positive error code if not valid and
18567 * -1 in case of an internal or API error.
18568 */
18569int
18570xmlSchemaCheckFacet(xmlSchemaFacetPtr facet,
18571 xmlSchemaTypePtr typeDecl,
18572 xmlSchemaParserCtxtPtr pctxt,
18573 const xmlChar * name ATTRIBUTE_UNUSED__attribute__((unused)))
18574{
18575 int ret = 0, ctxtGiven;
18576
18577 if ((facet == NULL((void*)0)) || (typeDecl == NULL((void*)0)))
18578 return(-1);
18579 /*
18580 * TODO: will the parser context be given if used from
18581 * the relaxNG module?
18582 */
18583 if (pctxt == NULL((void*)0))
18584 ctxtGiven = 0;
18585 else
18586 ctxtGiven = 1;
18587
18588 switch (facet->type) {
18589 case XML_SCHEMA_FACET_MININCLUSIVE:
18590 case XML_SCHEMA_FACET_MINEXCLUSIVE:
18591 case XML_SCHEMA_FACET_MAXINCLUSIVE:
18592 case XML_SCHEMA_FACET_MAXEXCLUSIVE:
18593 case XML_SCHEMA_FACET_ENUMERATION: {
18594 /*
18595 * Okay we need to validate the value
18596 * at that point.
18597 */
18598 xmlSchemaTypePtr base;
18599
18600 /* 4.3.5.5 Constraints on enumeration Schema Components
18601 * Schema Component Constraint: enumeration valid restriction
18602 * It is an `error` if any member of {value} is not in the
18603 * `value space` of {base type definition}.
18604 *
18605 * minInclusive, maxInclusive, minExclusive, maxExclusive:
18606 * The value `must` be in the
18607 * `value space` of the `base type`.
18608 */
18609 /*
18610 * This function is intended to deliver a compiled value
18611 * on the facet. In this implementation of XML Schemata the
18612 * type holding a facet, won't be a built-in type.
18613 * Thus to ensure that other API
18614 * calls (relaxng) do work, if the given type is a built-in
18615 * type, we will assume that the given built-in type *is
18616 * already* the base type.
18617 */
18618 if (typeDecl->type != XML_SCHEMA_TYPE_BASIC) {
18619 base = typeDecl->baseType;
18620 if (base == NULL((void*)0)) {
18621 PERROR_INT("xmlSchemaCheckFacet",xmlSchemaInternalErr((xmlSchemaAbstractCtxtPtr) pctxt, "xmlSchemaCheckFacet"
, "a type user derived type has no base type");
18622 "a type user derived type has no base type")xmlSchemaInternalErr((xmlSchemaAbstractCtxtPtr) pctxt, "xmlSchemaCheckFacet"
, "a type user derived type has no base type");
;
18623 return (-1);
18624 }
18625 } else
18626 base = typeDecl;
18627
18628 if (! ctxtGiven) {
18629 /*
18630 * A context is needed if called from RelaxNG.
18631 */
18632 pctxt = xmlSchemaNewParserCtxt("*");
18633 if (pctxt == NULL((void*)0))
18634 return (-1);
18635 }
18636 /*
18637 * NOTE: This call does not check the content nodes,
18638 * since they are not available:
18639 * facet->node is just the node holding the facet
18640 * definition, *not* the attribute holding the *value*
18641 * of the facet.
18642 */
18643 ret = xmlSchemaVCheckCVCSimpleType(
18644 ACTXT_CAST(xmlSchemaAbstractCtxtPtr) pctxt, facet->node, base,
18645 facet->value, &(facet->val), 1, 1, 0);
18646 if (ret != 0) {
18647 if (ret < 0) {
18648 /* No error message for RelaxNG. */
18649 if (ctxtGiven) {
18650 xmlSchemaCustomErr(ACTXT_CAST(xmlSchemaAbstractCtxtPtr) pctxt,
18651 XML_SCHEMAP_INTERNAL, facet->node, NULL((void*)0),
18652 "Internal error: xmlSchemaCheckFacet, "
18653 "failed to validate the value '%s' of the "
18654 "facet '%s' against the base type",
18655 facet->value, xmlSchemaFacetTypeToString(facet->type));
18656 }
18657 goto internal_error;
18658 }
18659 ret = XML_SCHEMAP_INVALID_FACET_VALUE;
18660 /* No error message for RelaxNG. */
18661 if (ctxtGiven) {
18662 xmlChar *str = NULL((void*)0);
18663
18664 xmlSchemaCustomErr(ACTXT_CAST(xmlSchemaAbstractCtxtPtr) pctxt,
18665 ret, facet->node, WXS_BASIC_CAST(xmlSchemaBasicItemPtr) facet,
18666 "The value '%s' of the facet does not validate "
18667 "against the base type '%s'",
18668 facet->value,
18669 xmlSchemaFormatQName(&str,
18670 base->targetNamespace, base->name));
18671 FREE_AND_NULL(str)if ((str) != ((void*)0)) { xmlFree((xmlChar *) (str)); str = (
(void*)0); }
;
18672 }
18673 goto exit;
18674 } else if (facet->val == NULL((void*)0)) {
18675 if (ctxtGiven) {
18676 PERROR_INT("xmlSchemaCheckFacet",xmlSchemaInternalErr((xmlSchemaAbstractCtxtPtr) pctxt, "xmlSchemaCheckFacet"
, "value was not computed");
18677 "value was not computed")xmlSchemaInternalErr((xmlSchemaAbstractCtxtPtr) pctxt, "xmlSchemaCheckFacet"
, "value was not computed");
;
18678 }
18679 TODO(*__xmlGenericError())((*__xmlGenericErrorContext()), "Unimplemented block at %s:%d\n"
, "xmlschemas.c", 18679);
18680 }
18681 break;
18682 }
18683 case XML_SCHEMA_FACET_PATTERN:
18684 facet->regexp = xmlRegexpCompile(facet->value);
18685 if (facet->regexp == NULL((void*)0)) {
18686 ret = XML_SCHEMAP_REGEXP_INVALID;
18687 /* No error message for RelaxNG. */
18688 if (ctxtGiven) {
18689 xmlSchemaCustomErr(ACTXT_CAST(xmlSchemaAbstractCtxtPtr) pctxt,
18690 ret, facet->node, WXS_BASIC_CAST(xmlSchemaBasicItemPtr) typeDecl,
18691 "The value '%s' of the facet 'pattern' is not a "
18692 "valid regular expression",
18693 facet->value, NULL((void*)0));
18694 }
18695 }
18696 break;
18697 case XML_SCHEMA_FACET_TOTALDIGITS:
18698 case XML_SCHEMA_FACET_FRACTIONDIGITS:
18699 case XML_SCHEMA_FACET_LENGTH:
18700 case XML_SCHEMA_FACET_MAXLENGTH:
18701 case XML_SCHEMA_FACET_MINLENGTH:
18702
18703 if (facet->type == XML_SCHEMA_FACET_TOTALDIGITS) {
18704 ret = xmlSchemaValidatePredefinedType(
18705 xmlSchemaGetBuiltInType(XML_SCHEMAS_PINTEGER),
18706 facet->value, &(facet->val));
18707 } else {
18708 ret = xmlSchemaValidatePredefinedType(
18709 xmlSchemaGetBuiltInType(XML_SCHEMAS_NNINTEGER),
18710 facet->value, &(facet->val));
18711 }
18712 if (ret != 0) {
18713 if (ret < 0) {
18714 /* No error message for RelaxNG. */
18715 if (ctxtGiven) {
18716 PERROR_INT("xmlSchemaCheckFacet",xmlSchemaInternalErr((xmlSchemaAbstractCtxtPtr) pctxt, "xmlSchemaCheckFacet"
, "validating facet value");
18717 "validating facet value")xmlSchemaInternalErr((xmlSchemaAbstractCtxtPtr) pctxt, "xmlSchemaCheckFacet"
, "validating facet value");
;
18718 }
18719 goto internal_error;
18720 }
18721 ret = XML_SCHEMAP_INVALID_FACET_VALUE;
18722 /* No error message for RelaxNG. */
18723 if (ctxtGiven) {
18724 /* error code */
18725 xmlSchemaCustomErr4(ACTXT_CAST(xmlSchemaAbstractCtxtPtr) pctxt,
18726 ret, facet->node, WXS_BASIC_CAST(xmlSchemaBasicItemPtr) typeDecl,
18727 "The value '%s' of the facet '%s' is not a valid '%s'",
18728 facet->value,
18729 xmlSchemaFacetTypeToString(facet->type),
18730 (facet->type != XML_SCHEMA_FACET_TOTALDIGITS) ?
18731 BAD_CAST(xmlChar *) "nonNegativeInteger" :
18732 BAD_CAST(xmlChar *) "positiveInteger",
18733 NULL((void*)0));
18734 }
18735 }
18736 break;
18737
18738 case XML_SCHEMA_FACET_WHITESPACE:{
18739 if (xmlStrEqual(facet->value, BAD_CAST(xmlChar *) "preserve")) {
18740 facet->whitespace = XML_SCHEMAS_FACET_PRESERVE1;
18741 } else if (xmlStrEqual(facet->value, BAD_CAST(xmlChar *) "replace")) {
18742 facet->whitespace = XML_SCHEMAS_FACET_REPLACE2;
18743 } else if (xmlStrEqual(facet->value, BAD_CAST(xmlChar *) "collapse")) {
18744 facet->whitespace = XML_SCHEMAS_FACET_COLLAPSE3;
18745 } else {
18746 ret = XML_SCHEMAP_INVALID_FACET_VALUE;
18747 /* No error message for RelaxNG. */
18748 if (ctxtGiven) {
18749 /* error was previously: XML_SCHEMAP_INVALID_WHITE_SPACE */
18750 xmlSchemaCustomErr(ACTXT_CAST(xmlSchemaAbstractCtxtPtr) pctxt,
18751 ret, facet->node, WXS_BASIC_CAST(xmlSchemaBasicItemPtr) typeDecl,
18752 "The value '%s' of the facet 'whitespace' is not "
18753 "valid", facet->value, NULL((void*)0));
18754 }
18755 }
18756 }
18757 default:
18758 break;
18759 }
18760exit:
18761 if ((! ctxtGiven) && (pctxt != NULL((void*)0)))
18762 xmlSchemaFreeParserCtxt(pctxt);
18763 return (ret);
18764internal_error:
18765 if ((! ctxtGiven) && (pctxt != NULL((void*)0)))
18766 xmlSchemaFreeParserCtxt(pctxt);
18767 return (-1);
18768}
18769
18770/**
18771 * xmlSchemaCheckFacetValues:
18772 * @typeDecl: the schema type definition
18773 * @ctxt: the schema parser context
18774 *
18775 * Checks the default values types, especially for facets
18776 */
18777static int
18778xmlSchemaCheckFacetValues(xmlSchemaTypePtr typeDecl,
18779 xmlSchemaParserCtxtPtr pctxt)
18780{
18781 int res, olderrs = pctxt->nberrors;
18782 const xmlChar *name = typeDecl->name;
18783 /*
18784 * NOTE: It is intended to use the facets list, instead
18785 * of facetSet.
18786 */
18787 if (typeDecl->facets != NULL((void*)0)) {
18788 xmlSchemaFacetPtr facet = typeDecl->facets;
18789
18790 /*
18791 * Temporarily assign the "schema" to the validation context
18792 * of the parser context. This is needed for NOTATION validation.
18793 */
18794 if (pctxt->vctxt == NULL((void*)0)) {
18795 if (xmlSchemaCreateVCtxtOnPCtxt(pctxt) == -1)
18796 return(-1);
18797 }
18798 pctxt->vctxt->schema = pctxt->schema;
18799 while (facet != NULL((void*)0)) {
18800 res = xmlSchemaCheckFacet(facet, typeDecl, pctxt, name);
18801 HFAILUREif (res == -1) goto exit_failure;
18802 facet = facet->next;
18803 }
18804 pctxt->vctxt->schema = NULL((void*)0);
18805 }
18806 if (olderrs != pctxt->nberrors)
18807 return(pctxt->err);
18808 return(0);
18809exit_failure:
18810 return(-1);
18811}
18812
18813/**
18814 * xmlSchemaGetCircModelGrDefRef:
18815 * @ctxtMGroup: the searched model group
18816 * @selfMGroup: the second searched model group
18817 * @particle: the first particle
18818 *
18819 * This one is intended to be used by
18820 * xmlSchemaCheckGroupDefCircular only.
18821 *
18822 * Returns the particle with the circular model group definition reference,
18823 * otherwise NULL.
18824 */
18825static xmlSchemaTreeItemPtr
18826xmlSchemaGetCircModelGrDefRef(xmlSchemaModelGroupDefPtr groupDef,
18827 xmlSchemaTreeItemPtr particle)
18828{
18829 xmlSchemaTreeItemPtr circ = NULL((void*)0);
18830 xmlSchemaTreeItemPtr term;
18831 xmlSchemaModelGroupDefPtr gdef;
18832
18833 for (; particle != NULL((void*)0); particle = particle->next) {
18834 term = particle->children;
18835 if (term == NULL((void*)0))
18836 continue;
18837 switch (term->type) {
18838 case XML_SCHEMA_TYPE_GROUP:
18839 gdef = (xmlSchemaModelGroupDefPtr) term;
18840 if (gdef == groupDef)
18841 return (particle);
18842 /*
18843 * Mark this model group definition to avoid infinite
18844 * recursion on circular references not yet examined.
18845 */
18846 if (gdef->flags & XML_SCHEMA_MODEL_GROUP_DEF_MARKED1<<0)
18847 continue;
18848 if (gdef->children != NULL((void*)0)) {
18849 gdef->flags |= XML_SCHEMA_MODEL_GROUP_DEF_MARKED1<<0;
18850 circ = xmlSchemaGetCircModelGrDefRef(groupDef,
18851 gdef->children->children);
18852 gdef->flags ^= XML_SCHEMA_MODEL_GROUP_DEF_MARKED1<<0;
18853 if (circ != NULL((void*)0))
18854 return (circ);
18855 }
18856 break;
18857 case XML_SCHEMA_TYPE_SEQUENCE:
18858 case XML_SCHEMA_TYPE_CHOICE:
18859 case XML_SCHEMA_TYPE_ALL:
18860 circ = xmlSchemaGetCircModelGrDefRef(groupDef, term->children);
18861 if (circ != NULL((void*)0))
18862 return (circ);
18863 break;
18864 default:
18865 break;
18866 }
18867 }
18868 return (NULL((void*)0));
18869}
18870
18871/**
18872 * xmlSchemaCheckGroupDefCircular:
18873 * @item: the model group definition
18874 * @ctxt: the parser context
18875 * @name: the name
18876 *
18877 * Checks for circular references to model group definitions.
18878 */
18879static void
18880xmlSchemaCheckGroupDefCircular(xmlSchemaModelGroupDefPtr item,
18881 xmlSchemaParserCtxtPtr ctxt)
18882{
18883 /*
18884 * Schema Component Constraint: Model Group Correct
18885 * 2 Circular groups are disallowed. That is, within the {particles}
18886 * of a group there must not be at any depth a particle whose {term}
18887 * is the group itself.
18888 */
18889 if ((item == NULL((void*)0)) ||
18890 (item->type != XML_SCHEMA_TYPE_GROUP) ||
18891 (item->children == NULL((void*)0)))
18892 return;
18893 {
18894 xmlSchemaTreeItemPtr circ;
18895
18896 circ = xmlSchemaGetCircModelGrDefRef(item, item->children->children);
18897 if (circ != NULL((void*)0)) {
18898 xmlChar *str = NULL((void*)0);
18899 /*
18900 * TODO: The error report is not adequate: this constraint
18901 * is defined for model groups but not definitions, but since
18902 * there cannot be any circular model groups without a model group
18903 * definition (if not using a construction API), we check those
18904 * definitions only.
18905 */
18906 xmlSchemaPCustomErr(ctxt,
18907 XML_SCHEMAP_MG_PROPS_CORRECT_2,
18908 NULL((void*)0), WXS_ITEM_NODE(circ)xmlSchemaGetComponentNode((xmlSchemaBasicItemPtr) (circ)),
18909 "Circular reference to the model group definition '%s' "
18910 "defined", xmlSchemaFormatQName(&str,
18911 item->targetNamespace, item->name));
18912 FREE_AND_NULL(str)if ((str) != ((void*)0)) { xmlFree((xmlChar *) (str)); str = (
(void*)0); }
18913 /*
18914 * NOTE: We will cut the reference to avoid further
18915 * confusion of the processor. This is a fatal error.
18916 */
18917 circ->children = NULL((void*)0);
18918 }
18919 }
18920}
18921
18922/**
18923 * xmlSchemaModelGroupToModelGroupDefFixup:
18924 * @ctxt: the parser context
18925 * @mg: the model group
18926 *
18927 * Assigns the model group of model group definitions to the "term"
18928 * of the referencing particle.
18929 * In xmlSchemaResolveModelGroupParticleReferences the model group
18930 * definitions were assigned to the "term", since needed for the
18931 * circularity check.
18932 *
18933 * Schema Component Constraint:
18934 * All Group Limited (cos-all-limited) (1.2)
18935 */
18936static void
18937xmlSchemaModelGroupToModelGroupDefFixup(
18938 xmlSchemaParserCtxtPtr ctxt ATTRIBUTE_UNUSED__attribute__((unused)),
18939 xmlSchemaModelGroupPtr mg)
18940{
18941 xmlSchemaParticlePtr particle = WXS_MODELGROUP_PARTICLE(mg)(xmlSchemaParticlePtr) (mg)->children;
18942
18943 while (particle != NULL((void*)0)) {
18944 if ((WXS_PARTICLE_TERM(particle)((xmlSchemaParticlePtr) (particle))->children == NULL((void*)0)) ||
18945 ((WXS_PARTICLE_TERM(particle)((xmlSchemaParticlePtr) (particle))->children)->type !=
18946 XML_SCHEMA_TYPE_GROUP))
18947 {
18948 particle = WXS_PTC_CAST(xmlSchemaParticlePtr) particle->next;
18949 continue;
18950 }
18951 if (WXS_MODELGROUPDEF_MODEL(WXS_PARTICLE_TERM(particle))((xmlSchemaModelGroupPtr) (((xmlSchemaParticlePtr) (particle)
)->children))->children
== NULL((void*)0)) {
18952 /*
18953 * TODO: Remove the particle.
18954 */
18955 WXS_PARTICLE_TERM(particle)((xmlSchemaParticlePtr) (particle))->children = NULL((void*)0);
18956 particle = WXS_PTC_CAST(xmlSchemaParticlePtr) particle->next;
18957 continue;
18958 }
18959 /*
18960 * Assign the model group to the {term} of the particle.
18961 */
18962 WXS_PARTICLE_TERM(particle)((xmlSchemaParticlePtr) (particle))->children =
18963 WXS_TREE_CAST(xmlSchemaTreeItemPtr) WXS_MODELGROUPDEF_MODEL(WXS_PARTICLE_TERM(particle))((xmlSchemaModelGroupPtr) (((xmlSchemaParticlePtr) (particle)
)->children))->children
;
18964
18965 particle = WXS_PTC_CAST(xmlSchemaParticlePtr) particle->next;
18966 }
18967}
18968
18969/**
18970 * xmlSchemaCheckAttrGroupCircularRecur:
18971 * @ctxtGr: the searched attribute group
18972 * @attr: the current attribute list to be processed
18973 *
18974 * This one is intended to be used by
18975 * xmlSchemaCheckAttrGroupCircular only.
18976 *
18977 * Returns the circular attribute group reference, otherwise NULL.
18978 */
18979static xmlSchemaQNameRefPtr
18980xmlSchemaCheckAttrGroupCircularRecur(xmlSchemaAttributeGroupPtr ctxtGr,
18981 xmlSchemaItemListPtr list)
18982{
18983 xmlSchemaAttributeGroupPtr gr;
18984 xmlSchemaQNameRefPtr ref, circ;
18985 int i;
18986 /*
18987 * We will search for an attribute group reference which
18988 * references the context attribute group.
18989 */
18990 for (i = 0; i < list->nbItems; i++) {
18991 ref = list->items[i];
18992 if ((ref->type == XML_SCHEMA_EXTRA_QNAMEREF) &&
18993 (ref->itemType == XML_SCHEMA_TYPE_ATTRIBUTEGROUP) &&
18994 (ref->item != NULL((void*)0)))
18995 {
18996 gr = WXS_ATTR_GROUP_CAST(xmlSchemaAttributeGroupPtr) ref->item;
18997 if (gr == ctxtGr)
18998 return(ref);
18999 if (gr->flags & XML_SCHEMAS_ATTRGROUP_MARKED1 << 2)
19000 continue;
19001 /*
19002 * Mark as visited to avoid infinite recursion on
19003 * circular references not yet examined.
19004 */
19005 if ((gr->attrUses) &&
19006 (gr->flags & XML_SCHEMAS_ATTRGROUP_HAS_REFS1 << 4))
19007 {
19008 gr->flags |= XML_SCHEMAS_ATTRGROUP_MARKED1 << 2;
19009 circ = xmlSchemaCheckAttrGroupCircularRecur(ctxtGr,
19010 (xmlSchemaItemListPtr) gr->attrUses);
19011 gr->flags ^= XML_SCHEMAS_ATTRGROUP_MARKED1 << 2;
19012 if (circ != NULL((void*)0))
19013 return (circ);
19014 }
19015
19016 }
19017 }
19018 return (NULL((void*)0));
19019}
19020
19021/**
19022 * xmlSchemaCheckAttrGroupCircular:
19023 * attrGr: the attribute group definition
19024 * @ctxt: the parser context
19025 * @name: the name
19026 *
19027 * Checks for circular references of attribute groups.
19028 */
19029static int
19030xmlSchemaCheckAttrGroupCircular(xmlSchemaAttributeGroupPtr attrGr,
19031 xmlSchemaParserCtxtPtr ctxt)
19032{
19033 /*
19034 * Schema Representation Constraint:
19035 * Attribute Group Definition Representation OK
19036 * 3 Circular group reference is disallowed outside <redefine>.
19037 * That is, unless this element information item's parent is
19038 * <redefine>, then among the [children], if any, there must
19039 * not be an <attributeGroup> with ref [attribute] which resolves
19040 * to the component corresponding to this <attributeGroup>. Indirect
19041 * circularity is also ruled out. That is, when QName resolution
19042 * (Schema Document) ($3.15.3) is applied to a `QName` arising from
19043 * any <attributeGroup>s with a ref [attribute] among the [children],
19044 * it must not be the case that a `QName` is encountered at any depth
19045 * which resolves to the component corresponding to this <attributeGroup>.
19046 */
19047 if (attrGr->attrUses == NULL((void*)0))
19048 return(0);
19049 else if ((attrGr->flags & XML_SCHEMAS_ATTRGROUP_HAS_REFS1 << 4) == 0)
19050 return(0);
19051 else {
19052 xmlSchemaQNameRefPtr circ;
19053
19054 circ = xmlSchemaCheckAttrGroupCircularRecur(attrGr,
19055 (xmlSchemaItemListPtr) attrGr->attrUses);
19056 if (circ != NULL((void*)0)) {
19057 xmlChar *str = NULL((void*)0);
19058 /*
19059 * TODO: Report the referenced attr group as QName.
19060 */
19061 xmlSchemaPCustomErr(ctxt,
19062 XML_SCHEMAP_SRC_ATTRIBUTE_GROUP_3,
19063 NULL((void*)0), WXS_ITEM_NODE(WXS_BASIC_CAST circ)xmlSchemaGetComponentNode((xmlSchemaBasicItemPtr) ((xmlSchemaBasicItemPtr
) circ))
,
19064 "Circular reference to the attribute group '%s' "
19065 "defined", xmlSchemaGetComponentQName(&str, attrGr));
19066 FREE_AND_NULL(str)if ((str) != ((void*)0)) { xmlFree((xmlChar *) (str)); str = (
(void*)0); }
;
19067 /*
19068 * NOTE: We will cut the reference to avoid further
19069 * confusion of the processor.
19070 * BADSPEC TODO: The spec should define how to process in this case.
19071 */
19072 circ->item = NULL((void*)0);
19073 return(ctxt->err);
19074 }
19075 }
19076 return(0);
19077}
19078
19079static int
19080xmlSchemaAttributeGroupExpandRefs(xmlSchemaParserCtxtPtr pctxt,
19081 xmlSchemaAttributeGroupPtr attrGr);
19082
19083/**
19084 * xmlSchemaExpandAttributeGroupRefs:
19085 * @pctxt: the parser context
19086 * @node: the node of the component holding the attribute uses
19087 * @completeWild: the intersected wildcard to be returned
19088 * @list: the attribute uses
19089 *
19090 * Substitutes contained attribute group references
19091 * for their attribute uses. Wildcards are intersected.
19092 * Attribute use prohibitions are removed from the list
19093 * and returned via the @prohibs list.
19094 * Pointlessness of attr. prohibs, if a matching attr. decl
19095 * is existent a well, are checked.
19096 */
19097static int
19098xmlSchemaExpandAttributeGroupRefs(xmlSchemaParserCtxtPtr pctxt,
19099 xmlSchemaBasicItemPtr item,
19100 xmlSchemaWildcardPtr *completeWild,
19101 xmlSchemaItemListPtr list,
19102 xmlSchemaItemListPtr prohibs)
19103{
19104 xmlSchemaAttributeGroupPtr gr;
19105 xmlSchemaAttributeUsePtr use;
19106 xmlSchemaItemListPtr sublist;
19107 int i, j;
19108 int created = (*completeWild == NULL((void*)0)) ? 0 : 1;
19109
19110 if (prohibs)
19111 prohibs->nbItems = 0;
19112
19113 for (i = 0; i < list->nbItems; i++) {
19114 use = list->items[i];
19115
19116 if (use->type == XML_SCHEMA_EXTRA_ATTR_USE_PROHIB) {
19117 if (prohibs == NULL((void*)0)) {
19118 PERROR_INT("xmlSchemaExpandAttributeGroupRefs",xmlSchemaInternalErr((xmlSchemaAbstractCtxtPtr) pctxt, "xmlSchemaExpandAttributeGroupRefs"
, "unexpected attr prohibition found");
19119 "unexpected attr prohibition found")xmlSchemaInternalErr((xmlSchemaAbstractCtxtPtr) pctxt, "xmlSchemaExpandAttributeGroupRefs"
, "unexpected attr prohibition found");
;
19120 return(-1);
19121 }
19122 /*
19123 * Remove from attribute uses.
19124 */
19125 if (xmlSchemaItemListRemove(list, i) == -1)
19126 return(-1);
19127 i--;
19128 /*
19129 * Note that duplicate prohibitions were already
19130 * handled at parsing time.
19131 */
19132 /*
19133 * Add to list of prohibitions.
19134 */
19135 xmlSchemaItemListAddSize(prohibs, 2, use);
19136 continue;
19137 }
19138 if ((use->type == XML_SCHEMA_EXTRA_QNAMEREF) &&
19139 ((WXS_QNAME_CAST(xmlSchemaQNameRefPtr) use)->itemType == XML_SCHEMA_TYPE_ATTRIBUTEGROUP))
19140 {
19141 if ((WXS_QNAME_CAST(xmlSchemaQNameRefPtr) use)->item == NULL((void*)0))
19142 return(-1);
19143 gr = WXS_ATTR_GROUP_CAST(xmlSchemaAttributeGroupPtr) (WXS_QNAME_CAST(xmlSchemaQNameRefPtr) use)->item;
19144 /*
19145 * Expand the referenced attr. group.
19146 * TODO: remove this, this is done in a previous step, so
19147 * already done here.
19148 */
19149 if ((gr->flags & XML_SCHEMAS_ATTRGROUP_WILDCARD_BUILDED1 << 0) == 0) {
19150 if (xmlSchemaAttributeGroupExpandRefs(pctxt, gr) == -1)
19151 return(-1);
19152 }
19153 /*
19154 * Build the 'complete' wildcard; i.e. intersect multiple
19155 * wildcards.
19156 */
19157 if (gr->attributeWildcard != NULL((void*)0)) {
19158 if (*completeWild == NULL((void*)0)) {
19159 *completeWild = gr->attributeWildcard;
19160 } else {
19161 if (! created) {
19162 xmlSchemaWildcardPtr tmpWild;
19163
19164 /*
19165 * Copy the first encountered wildcard as context,
19166 * except for the annotation.
19167 *
19168 * Although the complete wildcard might not correspond
19169 * to any node in the schema, we will anchor it on
19170 * the node of the owner component.
19171 */
19172 tmpWild = xmlSchemaAddWildcard(pctxt, pctxt->schema,
19173 XML_SCHEMA_TYPE_ANY_ATTRIBUTE,
19174 WXS_ITEM_NODE(item)xmlSchemaGetComponentNode((xmlSchemaBasicItemPtr) (item)));
19175 if (tmpWild == NULL((void*)0))
19176 return(-1);
19177 if (xmlSchemaCloneWildcardNsConstraints(pctxt,
19178 tmpWild, *completeWild) == -1)
19179 return (-1);
19180 tmpWild->processContents = (*completeWild)->processContents;
19181 *completeWild = tmpWild;
19182 created = 1;
19183 }
19184
19185 if (xmlSchemaIntersectWildcards(pctxt, *completeWild,
19186 gr->attributeWildcard) == -1)
19187 return(-1);
19188 }
19189 }
19190 /*
19191 * Just remove the reference if the referenced group does not
19192 * contain any attribute uses.
19193 */
19194 sublist = ((xmlSchemaItemListPtr) gr->attrUses);
19195 if ((sublist == NULL((void*)0)) || sublist->nbItems == 0) {
19196 if (xmlSchemaItemListRemove(list, i) == -1)
19197 return(-1);
19198 i--;
19199 continue;
19200 }
19201 /*
19202 * Add the attribute uses.
19203 */
19204 list->items[i] = sublist->items[0];
19205 if (sublist->nbItems != 1) {
19206 for (j = 1; j < sublist->nbItems; j++) {
19207 i++;
19208 if (xmlSchemaItemListInsert(list,
19209 sublist->items[j], i) == -1)
19210 return(-1);
19211 }
19212 }
19213 }
19214
19215 }
19216 /*
19217 * Handle pointless prohibitions of declared attributes.
19218 */
19219 if (prohibs && (prohibs->nbItems != 0) && (list->nbItems != 0)) {
19220 xmlSchemaAttributeUseProhibPtr prohib;
19221
19222 for (i = prohibs->nbItems -1; i >= 0; i--) {
19223 prohib = prohibs->items[i];
19224 for (j = 0; j < list->nbItems; j++) {
19225 use = list->items[j];
19226
19227 if ((prohib->name == WXS_ATTRUSE_DECL_NAME(use)(((xmlSchemaAttributeUsePtr) (use))->attrDecl)->name) &&
19228 (prohib->targetNamespace == WXS_ATTRUSE_DECL_TNS(use)(((xmlSchemaAttributeUsePtr) (use))->attrDecl)->targetNamespace))
19229 {
19230 xmlChar *str = NULL((void*)0);
19231
19232 xmlSchemaCustomWarning(ACTXT_CAST(xmlSchemaAbstractCtxtPtr) pctxt,
19233 XML_SCHEMAP_WARN_ATTR_POINTLESS_PROH,
19234 prohib->node, NULL((void*)0),
19235 "Skipping pointless attribute use prohibition "
19236 "'%s', since a corresponding attribute use "
19237 "exists already in the type definition",
19238 xmlSchemaFormatQName(&str,
19239 prohib->targetNamespace, prohib->name),
19240 NULL((void*)0), NULL((void*)0));
19241 FREE_AND_NULL(str)if ((str) != ((void*)0)) { xmlFree((xmlChar *) (str)); str = (
(void*)0); }
;
19242 /*
19243 * Remove the prohibition.
19244 */
19245 if (xmlSchemaItemListRemove(prohibs, i) == -1)
19246 return(-1);
19247 break;
19248 }
19249 }
19250 }
19251 }
19252 return(0);
19253}
19254
19255/**
19256 * xmlSchemaAttributeGroupExpandRefs:
19257 * @pctxt: the parser context
19258 * @attrGr: the attribute group definition
19259 *
19260 * Computation of:
19261 * {attribute uses} property
19262 * {attribute wildcard} property
19263 *
19264 * Substitutes contained attribute group references
19265 * for their attribute uses. Wildcards are intersected.
19266 */
19267static int
19268xmlSchemaAttributeGroupExpandRefs(xmlSchemaParserCtxtPtr pctxt,
19269 xmlSchemaAttributeGroupPtr attrGr)
19270{
19271 if ((attrGr->attrUses == NULL((void*)0)) ||
19272 (attrGr->flags & XML_SCHEMAS_ATTRGROUP_WILDCARD_BUILDED1 << 0))
19273 return(0);
19274
19275 attrGr->flags |= XML_SCHEMAS_ATTRGROUP_WILDCARD_BUILDED1 << 0;
19276 if (xmlSchemaExpandAttributeGroupRefs(pctxt, WXS_BASIC_CAST(xmlSchemaBasicItemPtr) attrGr,
19277 &(attrGr->attributeWildcard), attrGr->attrUses, NULL((void*)0)) == -1)
19278 return(-1);
19279 return(0);
19280}
19281
19282/**
19283 * xmlSchemaAttributeGroupExpandRefs:
19284 * @pctxt: the parser context
19285 * @attrGr: the attribute group definition
19286 *
19287 * Substitutes contained attribute group references
19288 * for their attribute uses. Wildcards are intersected.
19289 *
19290 * Schema Component Constraint:
19291 * Attribute Group Definition Properties Correct (ag-props-correct)
19292 */
19293static int
19294xmlSchemaCheckAGPropsCorrect(xmlSchemaParserCtxtPtr pctxt,
19295 xmlSchemaAttributeGroupPtr attrGr)
19296{
19297 /*
19298 * SPEC ag-props-correct
19299 * (1) "The values of the properties of an attribute group definition
19300 * must be as described in the property tableau in The Attribute
19301 * Group Definition Schema Component ($3.6.1), modulo the impact of
19302 * Missing Sub-components ($5.3);"
19303 */
19304
19305 if ((attrGr->attrUses != NULL((void*)0)) &&
19306 (WXS_LIST_CAST(xmlSchemaItemListPtr) attrGr->attrUses)->nbItems > 1)
19307 {
19308 xmlSchemaItemListPtr uses = WXS_LIST_CAST(xmlSchemaItemListPtr) attrGr->attrUses;
19309 xmlSchemaAttributeUsePtr use, tmp;
19310 int i, j, hasId = 0;
19311
19312 for (i = uses->nbItems -1; i >= 0; i--) {
19313 use = uses->items[i];
19314 /*
19315 * SPEC ag-props-correct
19316 * (2) "Two distinct members of the {attribute uses} must not have
19317 * {attribute declaration}s both of whose {name}s match and whose
19318 * {target namespace}s are identical."
19319 */
19320 if (i > 0) {
19321 for (j = i -1; j >= 0; j--) {
19322 tmp = uses->items[j];
19323 if ((WXS_ATTRUSE_DECL_NAME(use)(((xmlSchemaAttributeUsePtr) (use))->attrDecl)->name ==
19324 WXS_ATTRUSE_DECL_NAME(tmp)(((xmlSchemaAttributeUsePtr) (tmp))->attrDecl)->name) &&
19325 (WXS_ATTRUSE_DECL_TNS(use)(((xmlSchemaAttributeUsePtr) (use))->attrDecl)->targetNamespace ==
19326 WXS_ATTRUSE_DECL_TNS(tmp)(((xmlSchemaAttributeUsePtr) (tmp))->attrDecl)->targetNamespace))
19327 {
19328 xmlChar *str = NULL((void*)0);
19329
19330 xmlSchemaCustomErr(ACTXT_CAST(xmlSchemaAbstractCtxtPtr) pctxt,
19331 XML_SCHEMAP_AG_PROPS_CORRECT,
19332 attrGr->node, WXS_BASIC_CAST(xmlSchemaBasicItemPtr) attrGr,
19333 "Duplicate %s",
19334 xmlSchemaGetComponentDesignation(&str, use),
19335 NULL((void*)0));
19336 FREE_AND_NULL(str)if ((str) != ((void*)0)) { xmlFree((xmlChar *) (str)); str = (
(void*)0); }
;
19337 /*
19338 * Remove the duplicate.
19339 */
19340 if (xmlSchemaItemListRemove(uses, i) == -1)
19341 return(-1);
19342 goto next_use;
19343 }
19344 }
19345 }
19346 /*
19347 * SPEC ag-props-correct
19348 * (3) "Two distinct members of the {attribute uses} must not have
19349 * {attribute declaration}s both of whose {type definition}s are or
19350 * are derived from ID."
19351 * TODO: Does 'derived' include member-types of unions?
19352 */
19353 if (WXS_ATTRUSE_TYPEDEF(use)(((xmlSchemaAttributeUsePtr) ((xmlSchemaAttributeUsePtr) use)
)->attrDecl)->subtypes
!= NULL((void*)0)) {
19354 if (xmlSchemaIsDerivedFromBuiltInType(
19355 WXS_ATTRUSE_TYPEDEF(use)(((xmlSchemaAttributeUsePtr) ((xmlSchemaAttributeUsePtr) use)
)->attrDecl)->subtypes
, XML_SCHEMAS_ID))
19356 {
19357 if (hasId) {
19358 xmlChar *str = NULL((void*)0);
19359
19360 xmlSchemaCustomErr(ACTXT_CAST(xmlSchemaAbstractCtxtPtr) pctxt,
19361 XML_SCHEMAP_AG_PROPS_CORRECT,
19362 attrGr->node, WXS_BASIC_CAST(xmlSchemaBasicItemPtr) attrGr,
19363 "There must not exist more than one attribute "
19364 "declaration of type 'xs:ID' "
19365 "(or derived from 'xs:ID'). The %s violates this "
19366 "constraint",
19367 xmlSchemaGetComponentDesignation(&str, use),
19368 NULL((void*)0));
19369 FREE_AND_NULL(str)if ((str) != ((void*)0)) { xmlFree((xmlChar *) (str)); str = (
(void*)0); }
;
19370 if (xmlSchemaItemListRemove(uses, i) == -1)
19371 return(-1);
19372 }
19373 hasId = 1;
19374 }
19375 }
19376next_use: {}
19377 }
19378 }
19379 return(0);
19380}
19381
19382/**
19383 * xmlSchemaResolveAttrGroupReferences:
19384 * @attrgrpDecl: the schema attribute definition
19385 * @ctxt: the schema parser context
19386 * @name: the attribute name
19387 *
19388 * Resolves references to attribute group definitions.
19389 */
19390static int
19391xmlSchemaResolveAttrGroupReferences(xmlSchemaQNameRefPtr ref,
19392 xmlSchemaParserCtxtPtr ctxt)
19393{
19394 xmlSchemaAttributeGroupPtr group;
19395
19396 if (ref->item != NULL((void*)0))
19397 return(0);
19398 group = xmlSchemaGetAttributeGroup(ctxt->schema,
19399 ref->name,
19400 ref->targetNamespace);
19401 if (group == NULL((void*)0)) {
19402 xmlSchemaPResCompAttrErr(ctxt,
19403 XML_SCHEMAP_SRC_RESOLVE,
19404 NULL((void*)0), ref->node,
19405 "ref", ref->name, ref->targetNamespace,
19406 ref->itemType, NULL((void*)0));
19407 return(ctxt->err);
19408 }
19409 ref->item = WXS_BASIC_CAST(xmlSchemaBasicItemPtr) group;
19410 return(0);
19411}
19412
19413/**
19414 * xmlSchemaCheckAttrPropsCorrect:
19415 * @item: an schema attribute declaration/use
19416 * @ctxt: a schema parser context
19417 * @name: the name of the attribute
19418 *
19419 *
19420 * Schema Component Constraint:
19421 * Attribute Declaration Properties Correct (a-props-correct)
19422 *
19423 * Validates the value constraints of an attribute declaration/use.
19424 * NOTE that this needs the simple type definitions to be already
19425 * built and checked.
19426 */
19427static int
19428xmlSchemaCheckAttrPropsCorrect(xmlSchemaParserCtxtPtr pctxt,
19429 xmlSchemaAttributePtr attr)
19430{
19431
19432 /*
19433 * SPEC a-props-correct (1)
19434 * "The values of the properties of an attribute declaration must
19435 * be as described in the property tableau in The Attribute
19436 * Declaration Schema Component ($3.2.1), modulo the impact of
19437 * Missing Sub-components ($5.3)."
19438 */
19439
19440 if (WXS_ATTR_TYPEDEF(attr)(attr)->subtypes == NULL((void*)0))
19441 return(0);
19442
19443 if (attr->defValue != NULL((void*)0)) {
19444 int ret;
19445
19446 /*
19447 * SPEC a-props-correct (3)
19448 * "If the {type definition} is or is derived from ID then there
19449 * must not be a {value constraint}."
19450 */
19451 if (xmlSchemaIsDerivedFromBuiltInType(
19452 WXS_ATTR_TYPEDEF(attr)(attr)->subtypes, XML_SCHEMAS_ID))
19453 {
19454 xmlSchemaCustomErr(ACTXT_CAST(xmlSchemaAbstractCtxtPtr) pctxt,
19455 XML_SCHEMAP_A_PROPS_CORRECT_3,
19456 NULL((void*)0), WXS_BASIC_CAST(xmlSchemaBasicItemPtr) attr,
19457 "Value constraints are not allowed if the type definition "
19458 "is or is derived from xs:ID",
19459 NULL((void*)0), NULL((void*)0));
19460 return(pctxt->err);
19461 }
19462 /*
19463 * SPEC a-props-correct (2)
19464 * "if there is a {value constraint}, the canonical lexical
19465 * representation of its value must be `valid` with respect
19466 * to the {type definition} as defined in String Valid ($3.14.4)."
19467 * TODO: Don't care about the *canonical* stuff here, this requirement
19468 * will be removed in WXS 1.1 anyway.
19469 */
19470 ret = xmlSchemaVCheckCVCSimpleType(ACTXT_CAST(xmlSchemaAbstractCtxtPtr) pctxt,
19471 attr->node, WXS_ATTR_TYPEDEF(attr)(attr)->subtypes,
19472 attr->defValue, &(attr->defVal),
19473 1, 1, 0);
19474 if (ret != 0) {
19475 if (ret < 0) {
19476 PERROR_INT("xmlSchemaCheckAttrPropsCorrect",xmlSchemaInternalErr((xmlSchemaAbstractCtxtPtr) pctxt, "xmlSchemaCheckAttrPropsCorrect"
, "calling xmlSchemaVCheckCVCSimpleType()");
19477 "calling xmlSchemaVCheckCVCSimpleType()")xmlSchemaInternalErr((xmlSchemaAbstractCtxtPtr) pctxt, "xmlSchemaCheckAttrPropsCorrect"
, "calling xmlSchemaVCheckCVCSimpleType()");
;
19478 return(-1);
19479 }
19480 xmlSchemaCustomErr(ACTXT_CAST(xmlSchemaAbstractCtxtPtr) pctxt,
19481 XML_SCHEMAP_A_PROPS_CORRECT_2,
19482 NULL((void*)0), WXS_BASIC_CAST(xmlSchemaBasicItemPtr) attr,
19483 "The value of the value constraint is not valid",
19484 NULL((void*)0), NULL((void*)0));
19485 return(pctxt->err);
19486 }
19487 }
19488
19489 return(0);
19490}
19491
19492static xmlSchemaElementPtr
19493xmlSchemaCheckSubstGroupCircular(xmlSchemaElementPtr elemDecl,
19494 xmlSchemaElementPtr ancestor)
19495{
19496 xmlSchemaElementPtr ret;
19497
19498 if (WXS_SUBST_HEAD(ancestor)(ancestor)->refDecl == NULL((void*)0))
19499 return (NULL((void*)0));
19500 if (WXS_SUBST_HEAD(ancestor)(ancestor)->refDecl == elemDecl)
19501 return (ancestor);
19502
19503 if (WXS_SUBST_HEAD(ancestor)(ancestor)->refDecl->flags & XML_SCHEMAS_ELEM_CIRCULAR1 << 9)
19504 return (NULL((void*)0));
19505 WXS_SUBST_HEAD(ancestor)(ancestor)->refDecl->flags |= XML_SCHEMAS_ELEM_CIRCULAR1 << 9;
19506 ret = xmlSchemaCheckSubstGroupCircular(elemDecl,
19507 WXS_SUBST_HEAD(ancestor)(ancestor)->refDecl);
19508 WXS_SUBST_HEAD(ancestor)(ancestor)->refDecl->flags ^= XML_SCHEMAS_ELEM_CIRCULAR1 << 9;
19509
19510 return (ret);
19511}
19512
19513/**
19514 * xmlSchemaCheckElemPropsCorrect:
19515 * @ctxt: a schema parser context
19516 * @decl: the element declaration
19517 * @name: the name of the attribute
19518 *
19519 * Schema Component Constraint:
19520 * Element Declaration Properties Correct (e-props-correct)
19521 *
19522 * STATUS:
19523 * missing: (6)
19524 */
19525static int
19526xmlSchemaCheckElemPropsCorrect(xmlSchemaParserCtxtPtr pctxt,
19527 xmlSchemaElementPtr elemDecl)
19528{
19529 int ret = 0;
19530 xmlSchemaTypePtr typeDef = WXS_ELEM_TYPEDEF(elemDecl)(elemDecl)->subtypes;
19531 /*
19532 * SPEC (1) "The values of the properties of an element declaration
19533 * must be as described in the property tableau in The Element
19534 * Declaration Schema Component ($3.3.1), modulo the impact of Missing
19535 * Sub-components ($5.3)."
19536 */
19537 if (WXS_SUBST_HEAD(elemDecl)(elemDecl)->refDecl != NULL((void*)0)) {
19538 xmlSchemaElementPtr head = WXS_SUBST_HEAD(elemDecl)(elemDecl)->refDecl, circ;
19539
19540 xmlSchemaCheckElementDeclComponent(head, pctxt);
19541 /*
19542 * SPEC (3) "If there is a non-`absent` {substitution group
19543 * affiliation}, then {scope} must be global."
19544 */
19545 if ((elemDecl->flags & XML_SCHEMAS_ELEM_GLOBAL1 << 1) == 0) {
19546 xmlSchemaPCustomErr(pctxt,
19547 XML_SCHEMAP_E_PROPS_CORRECT_3,
19548 WXS_BASIC_CAST(xmlSchemaBasicItemPtr) elemDecl, NULL((void*)0),
19549 "Only global element declarations can have a "
19550 "substitution group affiliation", NULL((void*)0));
19551 ret = XML_SCHEMAP_E_PROPS_CORRECT_3;
19552 }
19553 /*
19554 * TODO: SPEC (6) "Circular substitution groups are disallowed.
19555 * That is, it must not be possible to return to an element declaration
19556 * by repeatedly following the {substitution group affiliation}
19557 * property."
19558 */
19559 if (head == elemDecl)
19560 circ = head;
19561 else if (WXS_SUBST_HEAD(head)(head)->refDecl != NULL((void*)0))
19562 circ = xmlSchemaCheckSubstGroupCircular(head, head);
19563 else
19564 circ = NULL((void*)0);
19565 if (circ != NULL((void*)0)) {
19566 xmlChar *strA = NULL((void*)0), *strB = NULL((void*)0);
19567
19568 xmlSchemaPCustomErrExt(pctxt,
19569 XML_SCHEMAP_E_PROPS_CORRECT_6,
19570 WXS_BASIC_CAST(xmlSchemaBasicItemPtr) circ, NULL((void*)0),
19571 "The element declaration '%s' defines a circular "
19572 "substitution group to element declaration '%s'",
19573 xmlSchemaGetComponentQName(&strA, circ),
19574 xmlSchemaGetComponentQName(&strB, head),
19575 NULL((void*)0));
19576 FREE_AND_NULL(strA)if ((strA) != ((void*)0)) { xmlFree((xmlChar *) (strA)); strA
= ((void*)0); }
19577 FREE_AND_NULL(strB)if ((strB) != ((void*)0)) { xmlFree((xmlChar *) (strB)); strB
= ((void*)0); }
19578 ret = XML_SCHEMAP_E_PROPS_CORRECT_6;
19579 }
19580 /*
19581 * SPEC (4) "If there is a {substitution group affiliation},
19582 * the {type definition}
19583 * of the element declaration must be validly derived from the {type
19584 * definition} of the {substitution group affiliation}, given the value
19585 * of the {substitution group exclusions} of the {substitution group
19586 * affiliation}, as defined in Type Derivation OK (Complex) ($3.4.6)
19587 * (if the {type definition} is complex) or as defined in
19588 * Type Derivation OK (Simple) ($3.14.6) (if the {type definition} is
19589 * simple)."
19590 *
19591 * NOTE: {substitution group exclusions} means the values of the
19592 * attribute "final".
19593 */
19594
19595 if (typeDef != WXS_ELEM_TYPEDEF(WXS_SUBST_HEAD(elemDecl))((elemDecl)->refDecl)->subtypes) {
19596 int set = 0;
19597
19598 if (head->flags & XML_SCHEMAS_ELEM_FINAL_EXTENSION1 << 15)
19599 set |= SUBSET_EXTENSION1<<1;
19600 if (head->flags & XML_SCHEMAS_ELEM_FINAL_RESTRICTION1 << 16)
19601 set |= SUBSET_RESTRICTION1<<0;
19602
19603 if (xmlSchemaCheckCOSDerivedOK(ACTXT_CAST(xmlSchemaAbstractCtxtPtr) pctxt, typeDef,
19604 WXS_ELEM_TYPEDEF(head)(head)->subtypes, set) != 0) {
19605 xmlChar *strA = NULL((void*)0), *strB = NULL((void*)0), *strC = NULL((void*)0);
19606
19607 ret = XML_SCHEMAP_E_PROPS_CORRECT_4;
19608 xmlSchemaPCustomErrExt(pctxt,
19609 XML_SCHEMAP_E_PROPS_CORRECT_4,
19610 WXS_BASIC_CAST(xmlSchemaBasicItemPtr) elemDecl, NULL((void*)0),
19611 "The type definition '%s' was "
19612 "either rejected by the substitution group "
19613 "affiliation '%s', or not validly derived from its type "
19614 "definition '%s'",
19615 xmlSchemaGetComponentQName(&strA, typeDef),
19616 xmlSchemaGetComponentQName(&strB, head),
19617 xmlSchemaGetComponentQName(&strC, WXS_ELEM_TYPEDEF(head)(head)->subtypes));
19618 FREE_AND_NULL(strA)if ((strA) != ((void*)0)) { xmlFree((xmlChar *) (strA)); strA
= ((void*)0); }
19619 FREE_AND_NULL(strB)if ((strB) != ((void*)0)) { xmlFree((xmlChar *) (strB)); strB
= ((void*)0); }
19620 FREE_AND_NULL(strC)if ((strC) != ((void*)0)) { xmlFree((xmlChar *) (strC)); strC
= ((void*)0); }
19621 }
19622 }
19623 }
19624 /*
19625 * SPEC (5) "If the {type definition} or {type definition}'s
19626 * {content type}
19627 * is or is derived from ID then there must not be a {value constraint}.
19628 * Note: The use of ID as a type definition for elements goes beyond
19629 * XML 1.0, and should be avoided if backwards compatibility is desired"
19630 */
19631 if ((elemDecl->value != NULL((void*)0)) &&
19632 ((WXS_IS_SIMPLE(typeDef)((typeDef->type == XML_SCHEMA_TYPE_SIMPLE) || ((typeDef->
type == XML_SCHEMA_TYPE_BASIC) && (typeDef->builtInType
!= XML_SCHEMAS_ANYTYPE)))
&&
19633 xmlSchemaIsDerivedFromBuiltInType(typeDef, XML_SCHEMAS_ID)) ||
19634 (WXS_IS_COMPLEX(typeDef)(((typeDef)->type == XML_SCHEMA_TYPE_COMPLEX) || ((typeDef
)->builtInType == XML_SCHEMAS_ANYTYPE))
&&
19635 WXS_HAS_SIMPLE_CONTENT(typeDef)((typeDef->contentType == XML_SCHEMA_CONTENT_SIMPLE) || (typeDef
->contentType == XML_SCHEMA_CONTENT_BASIC))
&&
19636 xmlSchemaIsDerivedFromBuiltInType(typeDef->contentTypeDef,
19637 XML_SCHEMAS_ID)))) {
19638
19639 ret = XML_SCHEMAP_E_PROPS_CORRECT_5;
19640 xmlSchemaPCustomErr(pctxt,
19641 XML_SCHEMAP_E_PROPS_CORRECT_5,
19642 WXS_BASIC_CAST(xmlSchemaBasicItemPtr) elemDecl, NULL((void*)0),
19643 "The type definition (or type definition's content type) is or "
19644 "is derived from ID; value constraints are not allowed in "
19645 "conjunction with such a type definition", NULL((void*)0));
19646 } else if (elemDecl->value != NULL((void*)0)) {
19647 int vcret;
19648 xmlNodePtr node = NULL((void*)0);
19649
19650 /*
19651 * SPEC (2) "If there is a {value constraint}, the canonical lexical
19652 * representation of its value must be `valid` with respect to the
19653 * {type definition} as defined in Element Default Valid (Immediate)
19654 * ($3.3.6)."
19655 */
19656 if (typeDef == NULL((void*)0)) {
19657 xmlSchemaPErr(pctxt, elemDecl->node,
19658 XML_SCHEMAP_INTERNAL,
19659 "Internal error: xmlSchemaCheckElemPropsCorrect, "
19660 "type is missing... skipping validation of "
19661 "the value constraint", NULL((void*)0), NULL((void*)0));
19662 return (-1);
19663 }
19664 if (elemDecl->node != NULL((void*)0)) {
19665 if (elemDecl->flags & XML_SCHEMAS_ELEM_FIXED1 << 3)
19666 node = (xmlNodePtr) xmlHasProp(elemDecl->node,
19667 BAD_CAST(xmlChar *) "fixed");
19668 else
19669 node = (xmlNodePtr) xmlHasProp(elemDecl->node,
19670 BAD_CAST(xmlChar *) "default");
19671 }
19672 vcret = xmlSchemaParseCheckCOSValidDefault(pctxt, node,
19673 typeDef, elemDecl->value, &(elemDecl->defVal));
19674 if (vcret != 0) {
19675 if (vcret < 0) {
19676 PERROR_INT("xmlSchemaElemCheckValConstr",xmlSchemaInternalErr((xmlSchemaAbstractCtxtPtr) pctxt, "xmlSchemaElemCheckValConstr"
, "failed to validate the value constraint of an " "element declaration"
);
19677 "failed to validate the value constraint of an "xmlSchemaInternalErr((xmlSchemaAbstractCtxtPtr) pctxt, "xmlSchemaElemCheckValConstr"
, "failed to validate the value constraint of an " "element declaration"
);
19678 "element declaration")xmlSchemaInternalErr((xmlSchemaAbstractCtxtPtr) pctxt, "xmlSchemaElemCheckValConstr"
, "failed to validate the value constraint of an " "element declaration"
);
;
19679 return (-1);
19680 }
19681 return (vcret);
19682 }
19683 }
19684
19685 return (ret);
19686}
19687
19688/**
19689 * xmlSchemaCheckElemSubstGroup:
19690 * @ctxt: a schema parser context
19691 * @decl: the element declaration
19692 * @name: the name of the attribute
19693 *
19694 * Schema Component Constraint:
19695 * Substitution Group (cos-equiv-class)
19696 *
19697 * In Libxml2 the subst. groups will be precomputed, in terms of that
19698 * a list will be built for each subst. group head, holding all direct
19699 * referents to this head.
19700 * NOTE that this function needs:
19701 * 1. circular subst. groups to be checked beforehand
19702 * 2. the declaration's type to be derived from the head's type
19703 *
19704 * STATUS:
19705 *
19706 */
19707static void
19708xmlSchemaCheckElemSubstGroup(xmlSchemaParserCtxtPtr ctxt,
19709 xmlSchemaElementPtr elemDecl)
19710{
19711 if ((WXS_SUBST_HEAD(elemDecl)(elemDecl)->refDecl == NULL((void*)0)) ||
19712 /* SPEC (1) "Its {abstract} is false." */
19713 (elemDecl->flags & XML_SCHEMAS_ELEM_ABSTRACT1 << 4))
19714 return;
19715 {
19716 xmlSchemaElementPtr head;
19717 xmlSchemaTypePtr headType, type;
19718 int set, methSet;
19719 /*
19720 * SPEC (2) "It is validly substitutable for HEAD subject to HEAD's
19721 * {disallowed substitutions} as the blocking constraint, as defined in
19722 * Substitution Group OK (Transitive) ($3.3.6)."
19723 */
19724 for (head = WXS_SUBST_HEAD(elemDecl)(elemDecl)->refDecl; head != NULL((void*)0);
19725 head = WXS_SUBST_HEAD(head)(head)->refDecl) {
19726 set = 0;
19727 methSet = 0;
19728 /*
19729 * The blocking constraints.
19730 */
19731 if (head->flags & XML_SCHEMAS_ELEM_BLOCK_SUBSTITUTION1 << 13)
19732 continue;
19733 headType = head->subtypes;
19734 type = elemDecl->subtypes;
19735 if (headType == type)
19736 goto add_member;
19737 if (head->flags & XML_SCHEMAS_ELEM_BLOCK_RESTRICTION1 << 12)
19738 set |= XML_SCHEMAS_TYPE_BLOCK_RESTRICTION1 << 19;
19739 if (head->flags & XML_SCHEMAS_ELEM_BLOCK_EXTENSION1 << 11)
19740 set |= XML_SCHEMAS_TYPE_BLOCK_EXTENSION1 << 18;
19741 /*
19742 * SPEC: Substitution Group OK (Transitive) (2.3)
19743 * "The set of all {derivation method}s involved in the
19744 * derivation of D's {type definition} from C's {type definition}
19745 * does not intersect with the union of the blocking constraint,
19746 * C's {prohibited substitutions} (if C is complex, otherwise the
19747 * empty set) and the {prohibited substitutions} (respectively the
19748 * empty set) of any intermediate {type definition}s in the
19749 * derivation of D's {type definition} from C's {type definition}."
19750 */
19751 /*
19752 * OPTIMIZE TODO: Optimize this a bit, since, if traversing the
19753 * subst.head axis, the methSet does not need to be computed for
19754 * the full depth over and over.
19755 */
19756 /*
19757 * The set of all {derivation method}s involved in the derivation
19758 */
19759 while ((type != NULL((void*)0)) && (type != headType) &&
19760 (type != type->baseType)) {
19761 if ((WXS_IS_EXTENSION(type)((type)->flags & 1 << 1)) &&
19762 ((methSet & XML_SCHEMAS_TYPE_BLOCK_RESTRICTION1 << 19) == 0))
19763 methSet |= XML_SCHEMAS_TYPE_BLOCK_EXTENSION1 << 18;
19764
19765 if (WXS_IS_RESTRICTION(type)((type)->flags & 1 << 2) &&
19766 ((methSet & XML_SCHEMAS_TYPE_BLOCK_RESTRICTION1 << 19) == 0))
19767 methSet |= XML_SCHEMAS_TYPE_BLOCK_RESTRICTION1 << 19;
19768
19769 type = type->baseType;
19770 }
19771 /*
19772 * The {prohibited substitutions} of all intermediate types +
19773 * the head's type.
19774 */
19775 type = elemDecl->subtypes->baseType;
19776 while (type != NULL((void*)0)) {
19777 if (WXS_IS_COMPLEX(type)(((type)->type == XML_SCHEMA_TYPE_COMPLEX) || ((type)->
builtInType == XML_SCHEMAS_ANYTYPE))
) {
19778 if ((type->flags &
19779 XML_SCHEMAS_TYPE_BLOCK_EXTENSION1 << 18) &&
19780 ((set & XML_SCHEMAS_TYPE_BLOCK_EXTENSION1 << 18) == 0))
19781 set |= XML_SCHEMAS_TYPE_BLOCK_EXTENSION1 << 18;
19782 if ((type->flags &
19783 XML_SCHEMAS_TYPE_BLOCK_RESTRICTION1 << 19) &&
19784 ((set & XML_SCHEMAS_TYPE_BLOCK_RESTRICTION1 << 19) == 0))
19785 set |= XML_SCHEMAS_TYPE_BLOCK_RESTRICTION1 << 19;
19786 } else
19787 break;
19788 if (type == headType)
19789 break;
19790 type = type->baseType;
19791 }
19792 if ((set != 0) &&
19793 (((set & XML_SCHEMAS_TYPE_BLOCK_EXTENSION1 << 18) &&
19794 (methSet & XML_SCHEMAS_TYPE_BLOCK_EXTENSION1 << 18)) ||
19795 ((set & XML_SCHEMAS_TYPE_BLOCK_RESTRICTION1 << 19) &&
19796 (methSet & XML_SCHEMAS_TYPE_BLOCK_RESTRICTION1 << 19)))) {
19797 continue;
19798 }
19799add_member:
19800 xmlSchemaAddElementSubstitutionMember(ctxt, head, elemDecl);
19801 if ((head->flags & XML_SCHEMAS_ELEM_SUBST_GROUP_HEAD1 << 17) == 0)
19802 head->flags |= XML_SCHEMAS_ELEM_SUBST_GROUP_HEAD1 << 17;
19803 }
19804 }
19805}
19806
19807#ifdef WXS_ELEM_DECL_CONS_ENABLED /* enable when finished */
19808/**
19809 * xmlSchemaCheckElementDeclComponent
19810 * @pctxt: the schema parser context
19811 * @ctxtComponent: the context component (an element declaration)
19812 * @ctxtParticle: the first particle of the context component
19813 * @searchParticle: the element declaration particle to be analysed
19814 *
19815 * Schema Component Constraint: Element Declarations Consistent
19816 */
19817static int
19818xmlSchemaCheckElementDeclConsistent(xmlSchemaParserCtxtPtr pctxt,
19819 xmlSchemaBasicItemPtr ctxtComponent,
19820 xmlSchemaParticlePtr ctxtParticle,
19821 xmlSchemaParticlePtr searchParticle,
19822 xmlSchemaParticlePtr curParticle,
19823 int search)
19824{
19825 return(0);
19826
19827 int ret = 0;
19828 xmlSchemaParticlePtr cur = curParticle;
19829 if (curParticle == NULL((void*)0)) {
19830 return(0);
19831 }
19832 if (WXS_PARTICLE_TERM(curParticle)((xmlSchemaParticlePtr) (curParticle))->children == NULL((void*)0)) {
19833 /*
19834 * Just return in this case. A missing "term" of the particle
19835 * might arise due to an invalid "term" component.
19836 */
19837 return(0);
19838 }
19839 while (cur != NULL((void*)0)) {
19840 switch (WXS_PARTICLE_TERM(cur)((xmlSchemaParticlePtr) (cur))->children->type) {
19841 case XML_SCHEMA_TYPE_ANY:
19842 break;
19843 case XML_SCHEMA_TYPE_ELEMENT:
19844 if (search == 0) {
19845 ret = xmlSchemaCheckElementDeclConsistent(pctxt,
19846 ctxtComponent, ctxtParticle, cur, ctxtParticle, 1);
19847 if (ret != 0)
19848 return(ret);
19849 } else {
19850 xmlSchemaElementPtr elem =
19851 WXS_ELEM_CAST(xmlSchemaElementPtr)(WXS_PARTICLE_TERM(cur)((xmlSchemaParticlePtr) (cur))->children);
19852 /*
19853 * SPEC Element Declarations Consistent:
19854 * "If the {particles} contains, either directly,
19855 * indirectly (that is, within the {particles} of a
19856 * contained model group, recursively) or `implicitly`
19857 * two or more element declaration particles with
19858 * the same {name} and {target namespace}, then
19859 * all their type definitions must be the same
19860 * top-level definition [...]"
19861 */
19862 if (xmlStrEqual(WXS_PARTICLE_TERM_AS_ELEM(cur)((xmlSchemaElementPtr) ((xmlSchemaParticlePtr) (cur))->children
)
->name,
19863 WXS_PARTICLE_TERM_AS_ELEM(searchParticle)((xmlSchemaElementPtr) ((xmlSchemaParticlePtr) (searchParticle
))->children)
->name) &&
19864 xmlStrEqual(WXS_PARTICLE_TERM_AS_ELEM(cur)((xmlSchemaElementPtr) ((xmlSchemaParticlePtr) (cur))->children
)
->targetNamespace,
19865 WXS_PARTICLE_TERM_AS_ELEM(searchParticle)((xmlSchemaElementPtr) ((xmlSchemaParticlePtr) (searchParticle
))->children)
->targetNamespace))
19866 {
19867 xmlChar *strA = NULL((void*)0), *strB = NULL((void*)0);
19868
19869 xmlSchemaCustomErr(ACTXT_CAST(xmlSchemaAbstractCtxtPtr) pctxt,
19870 /* TODO: error code */
19871 XML_SCHEMAP_COS_NONAMBIG,
19872 WXS_ITEM_NODE(cur)xmlSchemaGetComponentNode((xmlSchemaBasicItemPtr) (cur)), NULL((void*)0),
19873 "In the content model of %s, there are multiple "
19874 "element declarations for '%s' with different "
19875 "type definitions",
19876 xmlSchemaGetComponentDesignation(&strA,
19877 ctxtComponent),
19878 xmlSchemaFormatQName(&strB,
19879 WXS_PARTICLE_TERM_AS_ELEM(cur)((xmlSchemaElementPtr) ((xmlSchemaParticlePtr) (cur))->children
)
->targetNamespace,
19880 WXS_PARTICLE_TERM_AS_ELEM(cur)((xmlSchemaElementPtr) ((xmlSchemaParticlePtr) (cur))->children
)
->name));
19881 FREE_AND_NULL(strA)if ((strA) != ((void*)0)) { xmlFree((xmlChar *) (strA)); strA
= ((void*)0); }
;
19882 FREE_AND_NULL(strB)if ((strB) != ((void*)0)) { xmlFree((xmlChar *) (strB)); strB
= ((void*)0); }
;
19883 return(XML_SCHEMAP_COS_NONAMBIG);
19884 }
19885 }
19886 break;
19887 case XML_SCHEMA_TYPE_SEQUENCE: {
19888 break;
19889 }
19890 case XML_SCHEMA_TYPE_CHOICE:{
19891 /*
19892 xmlSchemaTreeItemPtr sub;
19893
19894 sub = WXS_PARTICLE_TERM(particle)->children; (xmlSchemaParticlePtr)
19895 while (sub != NULL) {
19896 ret = xmlSchemaCheckElementDeclConsistent(pctxt, ctxtComponent,
19897 ctxtParticle, ctxtElem);
19898 if (ret != 0)
19899 return(ret);
19900 sub = sub->next;
19901 }
19902 */
19903 break;
19904 }
19905 case XML_SCHEMA_TYPE_ALL:
19906 break;
19907 case XML_SCHEMA_TYPE_GROUP:
19908 break;
19909 default:
19910 xmlSchemaInternalErr2(ACTXT_CAST(xmlSchemaAbstractCtxtPtr) pctxt,
19911 "xmlSchemaCheckElementDeclConsistent",
19912 "found unexpected term of type '%s' in content model",
19913 WXS_ITEM_TYPE_NAME(WXS_PARTICLE_TERM(cur))xmlSchemaGetComponentTypeStr((xmlSchemaBasicItemPtr) (((xmlSchemaParticlePtr
) (cur))->children))
, NULL((void*)0));
19914 return(-1);
19915 }
19916 cur = (xmlSchemaParticlePtr) cur->next;
19917 }
19918
19919exit:
19920 return(ret);
19921}
19922#endif
19923
19924/**
19925 * xmlSchemaCheckElementDeclComponent
19926 * @item: an schema element declaration/particle
19927 * @ctxt: a schema parser context
19928 * @name: the name of the attribute
19929 *
19930 * Validates the value constraints of an element declaration.
19931 * Adds substitution group members.
19932 */
19933static void
19934xmlSchemaCheckElementDeclComponent(xmlSchemaElementPtr elemDecl,
19935 xmlSchemaParserCtxtPtr ctxt)
19936{
19937 if (elemDecl == NULL((void*)0))
19938 return;
19939 if (elemDecl->flags & XML_SCHEMAS_ELEM_INTERNAL_CHECKED1 << 18)
19940 return;
19941 elemDecl->flags |= XML_SCHEMAS_ELEM_INTERNAL_CHECKED1 << 18;
19942 if (xmlSchemaCheckElemPropsCorrect(ctxt, elemDecl) == 0) {
19943 /*
19944 * Adds substitution group members.
19945 */
19946 xmlSchemaCheckElemSubstGroup(ctxt, elemDecl);
19947 }
19948}
19949
19950/**
19951 * xmlSchemaResolveModelGroupParticleReferences:
19952 * @particle: a particle component
19953 * @ctxt: a parser context
19954 *
19955 * Resolves references of a model group's {particles} to
19956 * model group definitions and to element declarations.
19957 */
19958static void
19959xmlSchemaResolveModelGroupParticleReferences(
19960 xmlSchemaParserCtxtPtr ctxt,
19961 xmlSchemaModelGroupPtr mg)
19962{
19963 xmlSchemaParticlePtr particle = WXS_MODELGROUP_PARTICLE(mg)(xmlSchemaParticlePtr) (mg)->children;
19964 xmlSchemaQNameRefPtr ref;
19965 xmlSchemaBasicItemPtr refItem;
19966
19967 /*
19968 * URGENT TODO: Test this.
19969 */
19970 while (particle != NULL((void*)0)) {
19971 if ((WXS_PARTICLE_TERM(particle)((xmlSchemaParticlePtr) (particle))->children == NULL((void*)0)) ||
19972 ((WXS_PARTICLE_TERM(particle)((xmlSchemaParticlePtr) (particle))->children)->type !=
19973 XML_SCHEMA_EXTRA_QNAMEREF))
19974 {
19975 goto next_particle;
19976 }
19977 ref = WXS_QNAME_CAST(xmlSchemaQNameRefPtr) WXS_PARTICLE_TERM(particle)((xmlSchemaParticlePtr) (particle))->children;
19978 /*
19979 * Resolve the reference.
19980 * NULL the {term} by default.
19981 */
19982 particle->children = NULL((void*)0);
19983
19984 refItem = xmlSchemaGetNamedComponent(ctxt->schema,
19985 ref->itemType, ref->name, ref->targetNamespace);
19986 if (refItem == NULL((void*)0)) {
19987 xmlSchemaPResCompAttrErr(ctxt, XML_SCHEMAP_SRC_RESOLVE,
19988 NULL((void*)0), WXS_ITEM_NODE(particle)xmlSchemaGetComponentNode((xmlSchemaBasicItemPtr) (particle)), "ref", ref->name,
19989 ref->targetNamespace, ref->itemType, NULL((void*)0));
19990 /* TODO: remove the particle. */
19991 goto next_particle;
19992 }
19993 if (refItem->type == XML_SCHEMA_TYPE_GROUP) {
19994 if (WXS_MODELGROUPDEF_MODEL(refItem)((xmlSchemaModelGroupPtr) (refItem))->children == NULL((void*)0))
19995 /* TODO: remove the particle. */
19996 goto next_particle;
19997 /*
19998 * NOTE that we will assign the model group definition
19999 * itself to the "term" of the particle. This will ease
20000 * the check for circular model group definitions. After
20001 * that the "term" will be assigned the model group of the
20002 * model group definition.
20003 */
20004 if ((WXS_MODELGROUPDEF_MODEL(refItem)((xmlSchemaModelGroupPtr) (refItem))->children)->type ==
20005 XML_SCHEMA_TYPE_ALL) {
20006 /*
20007 * SPEC cos-all-limited (1)
20008 * SPEC cos-all-limited (1.2)
20009 * "It appears only as the value of one or both of the
20010 * following properties:"
20011 * (1.1) "the {model group} property of a model group
20012 * definition."
20013 * (1.2) "the {term} property of a particle [... of] the "
20014 * {content type} of a complex type definition."
20015 */
20016 xmlSchemaCustomErr(ACTXT_CAST(xmlSchemaAbstractCtxtPtr) ctxt,
20017 /* TODO: error code */
20018 XML_SCHEMAP_COS_ALL_LIMITED,
20019 WXS_ITEM_NODE(particle)xmlSchemaGetComponentNode((xmlSchemaBasicItemPtr) (particle)), NULL((void*)0),
20020 "A model group definition is referenced, but "
20021 "it contains an 'all' model group, which "
20022 "cannot be contained by model groups",
20023 NULL((void*)0), NULL((void*)0));
20024 /* TODO: remove the particle. */
20025 goto next_particle;
20026 }
20027 particle->children = (xmlSchemaTreeItemPtr) refItem;
20028 } else {
20029 /*
20030 * TODO: Are referenced element declarations the only
20031 * other components we expect here?
20032 */
20033 particle->children = (xmlSchemaTreeItemPtr) refItem;
20034 }
20035next_particle:
20036 particle = WXS_PTC_CAST(xmlSchemaParticlePtr) particle->next;
20037 }
20038}
20039
20040static int
20041xmlSchemaAreValuesEqual(xmlSchemaValPtr x,
20042 xmlSchemaValPtr y)
20043{
20044 xmlSchemaTypePtr tx, ty, ptx, pty;
20045 int ret;
20046
20047 while (x != NULL((void*)0)) {
20048 /* Same types. */
20049 tx = xmlSchemaGetBuiltInType(xmlSchemaGetValType(x));
20050 ty = xmlSchemaGetBuiltInType(xmlSchemaGetValType(y));
20051 ptx = xmlSchemaGetPrimitiveType(tx);
20052 pty = xmlSchemaGetPrimitiveType(ty);
20053 /*
20054 * (1) if a datatype T' is `derived` by `restriction` from an
20055 * atomic datatype T then the `value space` of T' is a subset of
20056 * the `value space` of T. */
20057 /*
20058 * (2) if datatypes T' and T'' are `derived` by `restriction`
20059 * from a common atomic ancestor T then the `value space`s of T'
20060 * and T'' may overlap.
20061 */
20062 if (ptx != pty)
20063 return(0);
20064 /*
20065 * We assume computed values to be normalized, so do a fast
20066 * string comparison for string based types.
20067 */
20068 if ((ptx->builtInType == XML_SCHEMAS_STRING) ||
20069 WXS_IS_ANY_SIMPLE_TYPE(ptx)(((ptx)->type == XML_SCHEMA_TYPE_BASIC) && ((ptx)->
builtInType == XML_SCHEMAS_ANYSIMPLETYPE))
) {
20070 if (! xmlStrEqual(
20071 xmlSchemaValueGetAsString(x),
20072 xmlSchemaValueGetAsString(y)))
20073 return (0);
20074 } else {
20075 ret = xmlSchemaCompareValuesWhtsp(
20076 x, XML_SCHEMA_WHITESPACE_PRESERVE,
20077 y, XML_SCHEMA_WHITESPACE_PRESERVE);
20078 if (ret == -2)
20079 return(-1);
20080 if (ret != 0)
20081 return(0);
20082 }
20083 /*
20084 * Lists.
20085 */
20086 x = xmlSchemaValueGetNext(x);
20087 if (x != NULL((void*)0)) {
20088 y = xmlSchemaValueGetNext(y);
20089 if (y == NULL((void*)0))
20090 return (0);
20091 } else if (xmlSchemaValueGetNext(y) != NULL((void*)0))
20092 return (0);
20093 else
20094 return (1);
20095 }
20096 return (0);
20097}
20098
20099/**
20100 * xmlSchemaResolveAttrUseReferences:
20101 * @item: an attribute use
20102 * @ctxt: a parser context
20103 *
20104 * Resolves the referenced attribute declaration.
20105 */
20106static int
20107xmlSchemaResolveAttrUseReferences(xmlSchemaAttributeUsePtr ause,
20108 xmlSchemaParserCtxtPtr ctxt)
20109{
20110 if ((ctxt == NULL((void*)0)) || (ause == NULL((void*)0)))
20111 return(-1);
20112 if ((ause->attrDecl == NULL((void*)0)) ||
20113 (ause->attrDecl->type != XML_SCHEMA_EXTRA_QNAMEREF))
20114 return(0);
20115
20116 {
20117 xmlSchemaQNameRefPtr ref = WXS_QNAME_CAST(xmlSchemaQNameRefPtr) ause->attrDecl;
20118
20119 /*
20120 * TODO: Evaluate, what errors could occur if the declaration is not
20121 * found.
20122 */
20123 ause->attrDecl = xmlSchemaGetAttributeDecl(ctxt->schema,
20124 ref->name, ref->targetNamespace);
20125 if (ause->attrDecl == NULL((void*)0)) {
20126 xmlSchemaPResCompAttrErr(ctxt,
20127 XML_SCHEMAP_SRC_RESOLVE,
20128 WXS_BASIC_CAST(xmlSchemaBasicItemPtr) ause, ause->node,
20129 "ref", ref->name, ref->targetNamespace,
20130 XML_SCHEMA_TYPE_ATTRIBUTE, NULL((void*)0));
20131 return(ctxt->err);;
20132 }
20133 }
20134 return(0);
20135}
20136
20137/**
20138 * xmlSchemaCheckAttrUsePropsCorrect:
20139 * @ctxt: a parser context
20140 * @use: an attribute use
20141 *
20142 * Schema Component Constraint:
20143 * Attribute Use Correct (au-props-correct)
20144 *
20145 */
20146static int
20147xmlSchemaCheckAttrUsePropsCorrect(xmlSchemaParserCtxtPtr ctxt,
20148 xmlSchemaAttributeUsePtr use)
20149{
20150 if ((ctxt == NULL((void*)0)) || (use == NULL((void*)0)))
20151 return(-1);
20152 if ((use->defValue == NULL((void*)0)) || (WXS_ATTRUSE_DECL(use)((xmlSchemaAttributeUsePtr) (use))->attrDecl == NULL((void*)0)) ||
20153 ((WXS_ATTRUSE_DECL(use)((xmlSchemaAttributeUsePtr) (use))->attrDecl)->type != XML_SCHEMA_TYPE_ATTRIBUTE))
20154 return(0);
20155
20156 /*
20157 * SPEC au-props-correct (1)
20158 * "The values of the properties of an attribute use must be as
20159 * described in the property tableau in The Attribute Use Schema
20160 * Component ($3.5.1), modulo the impact of Missing
20161 * Sub-components ($5.3)."
20162 */
20163
20164 if (((WXS_ATTRUSE_DECL(use)((xmlSchemaAttributeUsePtr) (use))->attrDecl)->defValue != NULL((void*)0)) &&
20165 ((WXS_ATTRUSE_DECL(use)((xmlSchemaAttributeUsePtr) (use))->attrDecl)->flags & XML_SCHEMAS_ATTR_FIXED1 << 9) &&
20166 ((use->flags & XML_SCHEMA_ATTR_USE_FIXED1<<0) == 0))
20167 {
20168 xmlSchemaPCustomErr(ctxt,
20169 XML_SCHEMAP_AU_PROPS_CORRECT_2,
20170 WXS_BASIC_CAST(xmlSchemaBasicItemPtr) use, NULL((void*)0),
20171 "The attribute declaration has a 'fixed' value constraint "
20172 ", thus the attribute use must also have a 'fixed' value "
20173 "constraint",
20174 NULL((void*)0));
20175 return(ctxt->err);
20176 }
20177 /*
20178 * Compute and check the value constraint's value.
20179 */
20180 if ((use->defVal != NULL((void*)0)) && (WXS_ATTRUSE_TYPEDEF(use)(((xmlSchemaAttributeUsePtr) ((xmlSchemaAttributeUsePtr) use)
)->attrDecl)->subtypes
!= NULL((void*)0))) {
20181 int ret;
20182 /*
20183 * TODO: The spec seems to be missing a check of the
20184 * value constraint of the attribute use. We will do it here.
20185 */
20186 /*
20187 * SPEC a-props-correct (3)
20188 */
20189 if (xmlSchemaIsDerivedFromBuiltInType(
20190 WXS_ATTRUSE_TYPEDEF(use)(((xmlSchemaAttributeUsePtr) ((xmlSchemaAttributeUsePtr) use)
)->attrDecl)->subtypes
, XML_SCHEMAS_ID))
20191 {
20192 xmlSchemaCustomErr(ACTXT_CAST(xmlSchemaAbstractCtxtPtr) ctxt,
20193 XML_SCHEMAP_AU_PROPS_CORRECT,
20194 NULL((void*)0), WXS_BASIC_CAST(xmlSchemaBasicItemPtr) use,
20195 "Value constraints are not allowed if the type definition "
20196 "is or is derived from xs:ID",
20197 NULL((void*)0), NULL((void*)0));
20198 return(ctxt->err);
20199 }
20200
20201 ret = xmlSchemaVCheckCVCSimpleType(ACTXT_CAST(xmlSchemaAbstractCtxtPtr) ctxt,
20202 use->node, WXS_ATTRUSE_TYPEDEF(use)(((xmlSchemaAttributeUsePtr) ((xmlSchemaAttributeUsePtr) use)
)->attrDecl)->subtypes
,
20203 use->defValue, &(use->defVal),
20204 1, 1, 0);
20205 if (ret != 0) {
20206 if (ret < 0) {
20207 PERROR_INT2("xmlSchemaCheckAttrUsePropsCorrect",xmlSchemaInternalErr((xmlSchemaAbstractCtxtPtr) ctxt, "xmlSchemaCheckAttrUsePropsCorrect"
, "calling xmlSchemaVCheckCVCSimpleType()");
20208 "calling xmlSchemaVCheckCVCSimpleType()")xmlSchemaInternalErr((xmlSchemaAbstractCtxtPtr) ctxt, "xmlSchemaCheckAttrUsePropsCorrect"
, "calling xmlSchemaVCheckCVCSimpleType()");
;
20209 return(-1);
20210 }
20211 xmlSchemaCustomErr(ACTXT_CAST(xmlSchemaAbstractCtxtPtr) ctxt,
20212 XML_SCHEMAP_AU_PROPS_CORRECT,
20213 NULL((void*)0), WXS_BASIC_CAST(xmlSchemaBasicItemPtr) use,
20214 "The value of the value constraint is not valid",
20215 NULL((void*)0), NULL((void*)0));
20216 return(ctxt->err);
20217 }
20218 }
20219 /*
20220 * SPEC au-props-correct (2)
20221 * "If the {attribute declaration} has a fixed
20222 * {value constraint}, then if the attribute use itself has a
20223 * {value constraint}, it must also be fixed and its value must match
20224 * that of the {attribute declaration}'s {value constraint}."
20225 */
20226 if (((WXS_ATTRUSE_DECL(use)((xmlSchemaAttributeUsePtr) (use))->attrDecl)->defVal != NULL((void*)0)) &&
20227 (((WXS_ATTRUSE_DECL(use)((xmlSchemaAttributeUsePtr) (use))->attrDecl)->flags & XML_SCHEMA_ATTR_USE_FIXED1<<0) == 0))
20228 {
20229 if (! xmlSchemaAreValuesEqual(use->defVal,
20230 (WXS_ATTRUSE_DECL(use)((xmlSchemaAttributeUsePtr) (use))->attrDecl)->defVal))
20231 {
20232 xmlSchemaPCustomErr(ctxt,
20233 XML_SCHEMAP_AU_PROPS_CORRECT_2,
20234 WXS_BASIC_CAST(xmlSchemaBasicItemPtr) use, NULL((void*)0),
20235 "The 'fixed' value constraint of the attribute use "
20236 "must match the attribute declaration's value "
20237 "constraint '%s'",
20238 (WXS_ATTRUSE_DECL(use)((xmlSchemaAttributeUsePtr) (use))->attrDecl)->defValue);
20239 }
20240 return(ctxt->err);
20241 }
20242 return(0);
20243}
20244
20245
20246
20247
20248/**
20249 * xmlSchemaResolveAttrTypeReferences:
20250 * @item: an attribute declaration
20251 * @ctxt: a parser context
20252 *
20253 * Resolves the referenced type definition component.
20254 */
20255static int
20256xmlSchemaResolveAttrTypeReferences(xmlSchemaAttributePtr item,
20257 xmlSchemaParserCtxtPtr ctxt)
20258{
20259 /*
20260 * The simple type definition corresponding to the <simpleType> element
20261 * information item in the [children], if present, otherwise the simple
20262 * type definition `resolved` to by the `actual value` of the type
20263 * [attribute], if present, otherwise the `simple ur-type definition`.
20264 */
20265 if (item->flags & XML_SCHEMAS_ATTR_INTERNAL_RESOLVED1 << 8)
20266 return(0);
20267 item->flags |= XML_SCHEMAS_ATTR_INTERNAL_RESOLVED1 << 8;
20268 if (item->subtypes != NULL((void*)0))
20269 return(0);
20270 if (item->typeName != NULL((void*)0)) {
20271 xmlSchemaTypePtr type;
20272
20273 type = xmlSchemaGetType(ctxt->schema, item->typeName,
20274 item->typeNs);
20275 if ((type == NULL((void*)0)) || (! WXS_IS_SIMPLE(type)((type->type == XML_SCHEMA_TYPE_SIMPLE) || ((type->type
== XML_SCHEMA_TYPE_BASIC) && (type->builtInType !=
XML_SCHEMAS_ANYTYPE)))
)) {
20276 xmlSchemaPResCompAttrErr(ctxt,
20277 XML_SCHEMAP_SRC_RESOLVE,
20278 WXS_BASIC_CAST(xmlSchemaBasicItemPtr) item, item->node,
20279 "type", item->typeName, item->typeNs,
20280 XML_SCHEMA_TYPE_SIMPLE, NULL((void*)0));
20281 return(ctxt->err);
20282 } else
20283 item->subtypes = type;
20284
20285 } else {
20286 /*
20287 * The type defaults to the xs:anySimpleType.
20288 */
20289 item->subtypes = xmlSchemaGetBuiltInType(XML_SCHEMAS_ANYSIMPLETYPE);
20290 }
20291 return(0);
20292}
20293
20294/**
20295 * xmlSchemaResolveIDCKeyReferences:
20296 * @idc: the identity-constraint definition
20297 * @ctxt: the schema parser context
20298 * @name: the attribute name
20299 *
20300 * Resolve keyRef references to key/unique IDCs.
20301 * Schema Component Constraint:
20302 * Identity-constraint Definition Properties Correct (c-props-correct)
20303 */
20304static int
20305xmlSchemaResolveIDCKeyReferences(xmlSchemaIDCPtr idc,
20306 xmlSchemaParserCtxtPtr pctxt)
20307{
20308 if (idc->type != XML_SCHEMA_TYPE_IDC_KEYREF)
20309 return(0);
20310 if (idc->ref->name != NULL((void*)0)) {
20311 idc->ref->item = (xmlSchemaBasicItemPtr)
20312 xmlSchemaGetIDC(pctxt->schema, idc->ref->name,
20313 idc->ref->targetNamespace);
20314 if (idc->ref->item == NULL((void*)0)) {
20315 /*
20316 * TODO: It is actually not an error to fail to resolve
20317 * at this stage. BUT we need to be that strict!
20318 */
20319 xmlSchemaPResCompAttrErr(pctxt,
20320 XML_SCHEMAP_SRC_RESOLVE,
20321 WXS_BASIC_CAST(xmlSchemaBasicItemPtr) idc, idc->node,
20322 "refer", idc->ref->name,
20323 idc->ref->targetNamespace,
20324 XML_SCHEMA_TYPE_IDC_KEY, NULL((void*)0));
20325 return(pctxt->err);
20326 } else if (idc->ref->item->type == XML_SCHEMA_TYPE_IDC_KEYREF) {
20327 /*
20328 * SPEC c-props-correct (1)
20329 */
20330 xmlSchemaCustomErr(ACTXT_CAST(xmlSchemaAbstractCtxtPtr) pctxt,
20331 XML_SCHEMAP_C_PROPS_CORRECT,
20332 NULL((void*)0), WXS_BASIC_CAST(xmlSchemaBasicItemPtr) idc,
20333 "The keyref references a keyref",
20334 NULL((void*)0), NULL((void*)0));
20335 idc->ref->item = NULL((void*)0);
20336 return(pctxt->err);
20337 } else {
20338 if (idc->nbFields !=
20339 ((xmlSchemaIDCPtr) idc->ref->item)->nbFields) {
20340 xmlChar *str = NULL((void*)0);
20341 xmlSchemaIDCPtr refer;
20342
20343 refer = (xmlSchemaIDCPtr) idc->ref->item;
20344 /*
20345 * SPEC c-props-correct(2)
20346 * "If the {identity-constraint category} is keyref,
20347 * the cardinality of the {fields} must equal that of
20348 * the {fields} of the {referenced key}.
20349 */
20350 xmlSchemaCustomErr(ACTXT_CAST(xmlSchemaAbstractCtxtPtr) pctxt,
20351 XML_SCHEMAP_C_PROPS_CORRECT,
20352 NULL((void*)0), WXS_BASIC_CAST(xmlSchemaBasicItemPtr) idc,
20353 "The cardinality of the keyref differs from the "
20354 "cardinality of the referenced key/unique '%s'",
20355 xmlSchemaFormatQName(&str, refer->targetNamespace,
20356 refer->name),
20357 NULL((void*)0));
20358 FREE_AND_NULL(str)if ((str) != ((void*)0)) { xmlFree((xmlChar *) (str)); str = (
(void*)0); }
20359 return(pctxt->err);
20360 }
20361 }
20362 }
20363 return(0);
20364}
20365
20366static int
20367xmlSchemaResolveAttrUseProhibReferences(xmlSchemaAttributeUseProhibPtr prohib,
20368 xmlSchemaParserCtxtPtr pctxt)
20369{
20370 if (xmlSchemaGetAttributeDecl(pctxt->schema, prohib->name,
20371 prohib->targetNamespace) == NULL((void*)0)) {
20372
20373 xmlSchemaPResCompAttrErr(pctxt,
20374 XML_SCHEMAP_SRC_RESOLVE,
20375 NULL((void*)0), prohib->node,
20376 "ref", prohib->name, prohib->targetNamespace,
20377 XML_SCHEMA_TYPE_ATTRIBUTE, NULL((void*)0));
20378 return(XML_SCHEMAP_SRC_RESOLVE);
20379 }
20380 return(0);
20381}
20382
20383#define WXS_REDEFINED_TYPE(c)(((xmlSchemaTypePtr) item)->flags & 1 << 30) \
20384(((xmlSchemaTypePtr) item)->flags & XML_SCHEMAS_TYPE_REDEFINED1 << 30)
20385
20386#define WXS_REDEFINED_MODEL_GROUP_DEF(c)(((xmlSchemaModelGroupDefPtr) item)->flags & 1<<
1)
\
20387(((xmlSchemaModelGroupDefPtr) item)->flags & XML_SCHEMA_MODEL_GROUP_DEF_REDEFINED1<<1)
20388
20389#define WXS_REDEFINED_ATTR_GROUP(c)(((xmlSchemaAttributeGroupPtr) item)->flags & 1 <<
3)
\
20390(((xmlSchemaAttributeGroupPtr) item)->flags & XML_SCHEMAS_ATTRGROUP_REDEFINED1 << 3)
20391
20392static int
20393xmlSchemaCheckSRCRedefineFirst(xmlSchemaParserCtxtPtr pctxt)
20394{
20395 int err = 0;
20396 xmlSchemaRedefPtr redef = WXS_CONSTRUCTOR(pctxt)(pctxt)->constructor->redefs;
20397 xmlSchemaBasicItemPtr prev, item;
20398 int wasRedefined;
20399
20400 if (redef == NULL((void*)0))
20401 return(0);
20402
20403 do {
20404 item = redef->item;
20405 /*
20406 * First try to locate the redefined component in the
20407 * schema graph starting with the redefined schema.
20408 * NOTE: According to this schema bug entry:
20409 * http://lists.w3.org/Archives/Public/www-xml-schema-comments/2005OctDec/0019.html
20410 * it's not clear if the referenced component needs to originate
20411 * from the <redefine>d schema _document_ or the schema; the latter
20412 * would include all imported and included sub-schemas of the
20413 * <redefine>d schema. Currently the latter approach is used.
20414 * SUPPLEMENT: It seems that the WG moves towards the latter
20415 * approach, so we are doing it right.
20416 *
20417 */
20418 prev = xmlSchemaFindRedefCompInGraph(
20419 redef->targetBucket, item->type,
20420 redef->refName, redef->refTargetNs);
20421 if (prev == NULL((void*)0)) {
20422 xmlChar *str = NULL((void*)0);
20423 xmlNodePtr node;
20424
20425 /*
20426 * SPEC src-redefine:
20427 * (6.2.1) "The `actual value` of its own name attribute plus
20428 * target namespace must successfully `resolve` to a model
20429 * group definition in I."
20430 * (7.2.1) "The `actual value` of its own name attribute plus
20431 * target namespace must successfully `resolve` to an attribute
20432 * group definition in I."
20433
20434 *
20435 * Note that, if we are redefining with the use of references
20436 * to components, the spec assumes the src-resolve to be used;
20437 * but this won't assure that we search only *inside* the
20438 * redefined schema.
20439 */
20440 if (redef->reference)
20441 node = WXS_ITEM_NODE(redef->reference)xmlSchemaGetComponentNode((xmlSchemaBasicItemPtr) (redef->
reference))
;
20442 else
20443 node = WXS_ITEM_NODE(item)xmlSchemaGetComponentNode((xmlSchemaBasicItemPtr) (item));
20444 xmlSchemaCustomErr(ACTXT_CAST(xmlSchemaAbstractCtxtPtr) pctxt,
20445 /*
20446 * TODO: error code.
20447 * Probably XML_SCHEMAP_SRC_RESOLVE, if this is using the
20448 * reference kind.
20449 */
20450 XML_SCHEMAP_SRC_REDEFINE, node, NULL((void*)0),
20451 "The %s '%s' to be redefined could not be found in "
20452 "the redefined schema",
20453 WXS_ITEM_TYPE_NAME(item)xmlSchemaGetComponentTypeStr((xmlSchemaBasicItemPtr) (item)),
20454 xmlSchemaFormatQName(&str, redef->refTargetNs,
20455 redef->refName));
20456 FREE_AND_NULL(str)if ((str) != ((void*)0)) { xmlFree((xmlChar *) (str)); str = (
(void*)0); }
;
20457 err = pctxt->err;
20458 redef = redef->next;
20459 continue;
20460 }
20461 /*
20462 * TODO: Obtaining and setting the redefinition state is really
20463 * clumsy.
20464 */
20465 wasRedefined = 0;
20466 switch (item->type) {
20467 case XML_SCHEMA_TYPE_COMPLEX:
20468 case XML_SCHEMA_TYPE_SIMPLE:
20469 if ((WXS_TYPE_CAST(xmlSchemaTypePtr) prev)->flags &
20470 XML_SCHEMAS_TYPE_REDEFINED1 << 30)
20471 {
20472 wasRedefined = 1;
20473 break;
20474 }
20475 /* Mark it as redefined. */
20476 (WXS_TYPE_CAST(xmlSchemaTypePtr) prev)->flags |= XML_SCHEMAS_TYPE_REDEFINED1 << 30;
20477 /*
20478 * Assign the redefined type to the
20479 * base type of the redefining type.
20480 * TODO: How
20481 */
20482 ((xmlSchemaTypePtr) item)->baseType =
20483 (xmlSchemaTypePtr) prev;
20484 break;
20485 case XML_SCHEMA_TYPE_GROUP:
20486 if ((WXS_MODEL_GROUPDEF_CAST(xmlSchemaModelGroupDefPtr) prev)->flags &
20487 XML_SCHEMA_MODEL_GROUP_DEF_REDEFINED1<<1)
20488 {
20489 wasRedefined = 1;
20490 break;
20491 }
20492 /* Mark it as redefined. */
20493 (WXS_MODEL_GROUPDEF_CAST(xmlSchemaModelGroupDefPtr) prev)->flags |=
20494 XML_SCHEMA_MODEL_GROUP_DEF_REDEFINED1<<1;
20495 if (redef->reference != NULL((void*)0)) {
20496 /*
20497 * Overwrite the QName-reference with the
20498 * referenced model group def.
20499 */
20500 (WXS_PTC_CAST(xmlSchemaParticlePtr) redef->reference)->children =
20501 WXS_TREE_CAST(xmlSchemaTreeItemPtr) prev;
20502 }
20503 redef->target = prev;
20504 break;
20505 case XML_SCHEMA_TYPE_ATTRIBUTEGROUP:
20506 if ((WXS_ATTR_GROUP_CAST(xmlSchemaAttributeGroupPtr) prev)->flags &
20507 XML_SCHEMAS_ATTRGROUP_REDEFINED1 << 3)
20508 {
20509 wasRedefined = 1;
20510 break;
20511 }
20512 (WXS_ATTR_GROUP_CAST(xmlSchemaAttributeGroupPtr) prev)->flags |=
20513 XML_SCHEMAS_ATTRGROUP_REDEFINED1 << 3;
20514 if (redef->reference != NULL((void*)0)) {
20515 /*
20516 * Assign the redefined attribute group to the
20517 * QName-reference component.
20518 * This is the easy case, since we will just
20519 * expand the redefined group.
20520 */
20521 (WXS_QNAME_CAST(xmlSchemaQNameRefPtr) redef->reference)->item = prev;
20522 redef->target = NULL((void*)0);
20523 } else {
20524 /*
20525 * This is the complicated case: we need
20526 * to apply src-redefine (7.2.2) at a later
20527 * stage, i.e. when attribute group references
20528 * have been expanded and simple types have
20529 * been fixed.
20530 */
20531 redef->target = prev;
20532 }
20533 break;
20534 default:
20535 PERROR_INT("xmlSchemaResolveRedefReferences",xmlSchemaInternalErr((xmlSchemaAbstractCtxtPtr) pctxt, "xmlSchemaResolveRedefReferences"
, "Unexpected redefined component type");
20536 "Unexpected redefined component type")xmlSchemaInternalErr((xmlSchemaAbstractCtxtPtr) pctxt, "xmlSchemaResolveRedefReferences"
, "Unexpected redefined component type");
;
20537 return(-1);
20538 }
20539 if (wasRedefined) {
20540 xmlChar *str = NULL((void*)0);
20541 xmlNodePtr node;
20542
20543 if (redef->reference)
20544 node = WXS_ITEM_NODE(redef->reference)xmlSchemaGetComponentNode((xmlSchemaBasicItemPtr) (redef->
reference))
;
20545 else
20546 node = WXS_ITEM_NODE(redef->item)xmlSchemaGetComponentNode((xmlSchemaBasicItemPtr) (redef->
item))
;
20547
20548 xmlSchemaCustomErr(ACTXT_CAST(xmlSchemaAbstractCtxtPtr) pctxt,
20549 /* TODO: error code. */
20550 XML_SCHEMAP_SRC_REDEFINE,
20551 node, NULL((void*)0),
20552 "The referenced %s was already redefined. Multiple "
20553 "redefinition of the same component is not supported",
20554 xmlSchemaGetComponentDesignation(&str, prev),
20555 NULL((void*)0));
20556 FREE_AND_NULL(str)if ((str) != ((void*)0)) { xmlFree((xmlChar *) (str)); str = (
(void*)0); }
20557 err = pctxt->err;
20558 redef = redef->next;
20559 continue;
20560 }
20561 redef = redef->next;
20562 } while (redef != NULL((void*)0));
20563
20564 return(err);
20565}
20566
20567static int
20568xmlSchemaCheckSRCRedefineSecond(xmlSchemaParserCtxtPtr pctxt)
20569{
20570 int err = 0;
20571 xmlSchemaRedefPtr redef = WXS_CONSTRUCTOR(pctxt)(pctxt)->constructor->redefs;
20572 xmlSchemaBasicItemPtr item;
20573
20574 if (redef == NULL((void*)0))
20575 return(0);
20576
20577 do {
20578 if (redef->target == NULL((void*)0)) {
20579 redef = redef->next;
20580 continue;
20581 }
20582 item = redef->item;
20583
20584 switch (item->type) {
20585 case XML_SCHEMA_TYPE_SIMPLE:
20586 case XML_SCHEMA_TYPE_COMPLEX:
20587 /*
20588 * Since the spec wants the {name} of the redefined
20589 * type to be 'absent', we'll NULL it.
20590 */
20591 (WXS_TYPE_CAST(xmlSchemaTypePtr) redef->target)->name = NULL((void*)0);
20592
20593 /*
20594 * TODO: Seems like there's nothing more to do. The normal
20595 * inheritance mechanism is used. But not 100% sure.
20596 */
20597 break;
20598 case XML_SCHEMA_TYPE_GROUP:
20599 /*
20600 * URGENT TODO:
20601 * SPEC src-redefine:
20602 * (6.2.2) "The {model group} of the model group definition
20603 * which corresponds to it per XML Representation of Model
20604 * Group Definition Schema Components ($3.7.2) must be a
20605 * `valid restriction` of the {model group} of that model
20606 * group definition in I, as defined in Particle Valid
20607 * (Restriction) ($3.9.6)."
20608 */
20609 break;
20610 case XML_SCHEMA_TYPE_ATTRIBUTEGROUP:
20611 /*
20612 * SPEC src-redefine:
20613 * (7.2.2) "The {attribute uses} and {attribute wildcard} of
20614 * the attribute group definition which corresponds to it
20615 * per XML Representation of Attribute Group Definition Schema
20616 * Components ($3.6.2) must be `valid restrictions` of the
20617 * {attribute uses} and {attribute wildcard} of that attribute
20618 * group definition in I, as defined in clause 2, clause 3 and
20619 * clause 4 of Derivation Valid (Restriction, Complex)
20620 * ($3.4.6) (where references to the base type definition are
20621 * understood as references to the attribute group definition
20622 * in I)."
20623 */
20624 err = xmlSchemaCheckDerivationOKRestriction2to4(pctxt,
20625 XML_SCHEMA_ACTION_REDEFINE1,
20626 item, redef->target,
20627 (WXS_ATTR_GROUP_CAST(xmlSchemaAttributeGroupPtr) item)->attrUses,
20628 (WXS_ATTR_GROUP_CAST(xmlSchemaAttributeGroupPtr) redef->target)->attrUses,
20629 (WXS_ATTR_GROUP_CAST(xmlSchemaAttributeGroupPtr) item)->attributeWildcard,
20630 (WXS_ATTR_GROUP_CAST(xmlSchemaAttributeGroupPtr) redef->target)->attributeWildcard);
20631 if (err == -1)
20632 return(-1);
20633 break;
20634 default:
20635 break;
20636 }
20637 redef = redef->next;
20638 } while (redef != NULL((void*)0));
20639 return(0);
20640}
20641
20642
20643static int
20644xmlSchemaAddComponents(xmlSchemaParserCtxtPtr pctxt,
20645 xmlSchemaBucketPtr bucket)
20646{
20647 xmlSchemaBasicItemPtr item;
20648 int err;
20649 xmlHashTablePtr *table;
20650 const xmlChar *name;
20651 int i;
20652
20653#define WXS_GET_GLOBAL_HASH(c, slot){ if (((((c)->type) == 0) || (((c)->type) == 1))) table
= &(((xmlSchemaImportPtr) ((c)))->schema->slot); else
table = &(((xmlSchemaIncludePtr) ((c)))->ownerImport->
schema->slot); }
{ \
20654 if (WXS_IS_BUCKET_IMPMAIN((c)->type)((((c)->type) == 0) || (((c)->type) == 1))) \
20655 table = &(WXS_IMPBUCKET((c))((xmlSchemaImportPtr) ((c)))->schema->slot); \
20656 else \
20657 table = &(WXS_INCBUCKET((c))((xmlSchemaIncludePtr) ((c)))->ownerImport->schema->slot); }
20658
20659 /*
20660 * Add global components to the schema's hash tables.
20661 * This is the place where duplicate components will be
20662 * detected.
20663 * TODO: I think normally we should support imports of the
20664 * same namespace from multiple locations. We don't do currently,
20665 * but if we do then according to:
20666 * http://www.w3.org/Bugs/Public/show_bug.cgi?id=2224
20667 * we would need, if imported directly, to import redefined
20668 * components as well to be able to catch clashing components.
20669 * (I hope I'll still know what this means after some months :-()
20670 */
20671 if (bucket == NULL((void*)0))
20672 return(-1);
20673 if (bucket->flags & XML_SCHEMA_BUCKET_COMPS_ADDED1<<1)
20674 return(0);
20675 bucket->flags |= XML_SCHEMA_BUCKET_COMPS_ADDED1<<1;
20676
20677 for (i = 0; i < bucket->globals->nbItems; i++) {
20678 item = bucket->globals->items[i];
20679 table = NULL((void*)0);
20680 switch (item->type) {
20681 case XML_SCHEMA_TYPE_COMPLEX:
20682 case XML_SCHEMA_TYPE_SIMPLE:
20683 if (WXS_REDEFINED_TYPE(item)(((xmlSchemaTypePtr) item)->flags & 1 << 30))
20684 continue;
20685 name = (WXS_TYPE_CAST(xmlSchemaTypePtr) item)->name;
20686 WXS_GET_GLOBAL_HASH(bucket, typeDecl){ if (((((bucket)->type) == 0) || (((bucket)->type) == 1
))) table = &(((xmlSchemaImportPtr) ((bucket)))->schema
->typeDecl); else table = &(((xmlSchemaIncludePtr) ((bucket
)))->ownerImport->schema->typeDecl); }
20687 break;
20688 case XML_SCHEMA_TYPE_ELEMENT:
20689 name = (WXS_ELEM_CAST(xmlSchemaElementPtr) item)->name;
20690 WXS_GET_GLOBAL_HASH(bucket, elemDecl){ if (((((bucket)->type) == 0) || (((bucket)->type) == 1
))) table = &(((xmlSchemaImportPtr) ((bucket)))->schema
->elemDecl); else table = &(((xmlSchemaIncludePtr) ((bucket
)))->ownerImport->schema->elemDecl); }
20691 break;
20692 case XML_SCHEMA_TYPE_ATTRIBUTE:
20693 name = (WXS_ATTR_CAST(xmlSchemaAttributePtr) item)->name;
20694 WXS_GET_GLOBAL_HASH(bucket, attrDecl){ if (((((bucket)->type) == 0) || (((bucket)->type) == 1
))) table = &(((xmlSchemaImportPtr) ((bucket)))->schema
->attrDecl); else table = &(((xmlSchemaIncludePtr) ((bucket
)))->ownerImport->schema->attrDecl); }
20695 break;
20696 case XML_SCHEMA_TYPE_GROUP:
20697 if (WXS_REDEFINED_MODEL_GROUP_DEF(item)(((xmlSchemaModelGroupDefPtr) item)->flags & 1<<
1)
)
20698 continue;
20699 name = (WXS_MODEL_GROUPDEF_CAST(xmlSchemaModelGroupDefPtr) item)->name;
20700 WXS_GET_GLOBAL_HASH(bucket, groupDecl){ if (((((bucket)->type) == 0) || (((bucket)->type) == 1
))) table = &(((xmlSchemaImportPtr) ((bucket)))->schema
->groupDecl); else table = &(((xmlSchemaIncludePtr) ((
bucket)))->ownerImport->schema->groupDecl); }
20701 break;
20702 case XML_SCHEMA_TYPE_ATTRIBUTEGROUP:
20703 if (WXS_REDEFINED_ATTR_GROUP(item)(((xmlSchemaAttributeGroupPtr) item)->flags & 1 <<
3)
)
20704 continue;
20705 name = (WXS_ATTR_GROUP_CAST(xmlSchemaAttributeGroupPtr) item)->name;
20706 WXS_GET_GLOBAL_HASH(bucket, attrgrpDecl){ if (((((bucket)->type) == 0) || (((bucket)->type) == 1
))) table = &(((xmlSchemaImportPtr) ((bucket)))->schema
->attrgrpDecl); else table = &(((xmlSchemaIncludePtr) (
(bucket)))->ownerImport->schema->attrgrpDecl); }
20707 break;
20708 case XML_SCHEMA_TYPE_IDC_KEY:
20709 case XML_SCHEMA_TYPE_IDC_UNIQUE:
20710 case XML_SCHEMA_TYPE_IDC_KEYREF:
20711 name = (WXS_IDC_CAST(xmlSchemaIDCPtr) item)->name;
20712 WXS_GET_GLOBAL_HASH(bucket, idcDef){ if (((((bucket)->type) == 0) || (((bucket)->type) == 1
))) table = &(((xmlSchemaImportPtr) ((bucket)))->schema
->idcDef); else table = &(((xmlSchemaIncludePtr) ((bucket
)))->ownerImport->schema->idcDef); }
20713 break;
20714 case XML_SCHEMA_TYPE_NOTATION:
20715 name = ((xmlSchemaNotationPtr) item)->name;
20716 WXS_GET_GLOBAL_HASH(bucket, notaDecl){ if (((((bucket)->type) == 0) || (((bucket)->type) == 1
))) table = &(((xmlSchemaImportPtr) ((bucket)))->schema
->notaDecl); else table = &(((xmlSchemaIncludePtr) ((bucket
)))->ownerImport->schema->notaDecl); }
20717 break;
20718 default:
20719 PERROR_INT("xmlSchemaAddComponents",xmlSchemaInternalErr((xmlSchemaAbstractCtxtPtr) pctxt, "xmlSchemaAddComponents"
, "Unexpected global component type");
20720 "Unexpected global component type")xmlSchemaInternalErr((xmlSchemaAbstractCtxtPtr) pctxt, "xmlSchemaAddComponents"
, "Unexpected global component type");
;
20721 continue;
20722 }
20723 if (*table == NULL((void*)0)) {
20724 *table = xmlHashCreateDict(10, pctxt->dict);
20725 if (*table == NULL((void*)0)) {
20726 PERROR_INT("xmlSchemaAddComponents",xmlSchemaInternalErr((xmlSchemaAbstractCtxtPtr) pctxt, "xmlSchemaAddComponents"
, "failed to create a component hash table");
20727 "failed to create a component hash table")xmlSchemaInternalErr((xmlSchemaAbstractCtxtPtr) pctxt, "xmlSchemaAddComponents"
, "failed to create a component hash table");
;
20728 return(-1);
20729 }
20730 }
20731 err = xmlHashAddEntry(*table, name, item);
20732 if (err != 0) {
20733 xmlChar *str = NULL((void*)0);
20734
20735 xmlSchemaCustomErr(ACTXT_CAST(xmlSchemaAbstractCtxtPtr) pctxt,
20736 XML_SCHEMAP_REDEFINED_TYPE,
20737 WXS_ITEM_NODE(item)xmlSchemaGetComponentNode((xmlSchemaBasicItemPtr) (item)),
20738 WXS_BASIC_CAST(xmlSchemaBasicItemPtr) item,
20739 "A global %s '%s' does already exist",
20740 WXS_ITEM_TYPE_NAME(item)xmlSchemaGetComponentTypeStr((xmlSchemaBasicItemPtr) (item)),
20741 xmlSchemaGetComponentQName(&str, item));
20742 FREE_AND_NULL(str)if ((str) != ((void*)0)) { xmlFree((xmlChar *) (str)); str = (
(void*)0); }
;
20743 }
20744 }
20745 /*
20746 * Process imported/included schemas.
20747 */
20748 if (bucket->relations != NULL((void*)0)) {
20749 xmlSchemaSchemaRelationPtr rel = bucket->relations;
20750 do {
20751 if ((rel->bucket != NULL((void*)0)) &&
20752 ((rel->bucket->flags & XML_SCHEMA_BUCKET_COMPS_ADDED1<<1) == 0)) {
20753 if (xmlSchemaAddComponents(pctxt, rel->bucket) == -1)
20754 return(-1);
20755 }
20756 rel = rel->next;
20757 } while (rel != NULL((void*)0));
20758 }
20759 return(0);
20760}
20761
20762static int
20763xmlSchemaFixupComponents(xmlSchemaParserCtxtPtr pctxt,
20764 xmlSchemaBucketPtr rootBucket)
20765{
20766 xmlSchemaConstructionCtxtPtr con = pctxt->constructor;
20767 xmlSchemaTreeItemPtr item, *items;
20768 int nbItems, i, ret = 0;
20769 xmlSchemaBucketPtr oldbucket = con->bucket;
20770 xmlSchemaElementPtr elemDecl;
20771
20772#define FIXHFAILUREif (pctxt->err == XML_SCHEMAP_INTERNAL) goto exit_failure; if (pctxt->err == XML_SCHEMAP_INTERNAL) goto exit_failure;
20773
20774 if ((con->pending == NULL((void*)0)) ||
20775 (con->pending->nbItems == 0))
20776 return(0);
20777
20778 /*
20779 * Since xmlSchemaFixupComplexType() will create new particles
20780 * (local components), and those particle components need a bucket
20781 * on the constructor, we'll assure here that the constructor has
20782 * a bucket.
20783 * TODO: Think about storing locals _only_ on the main bucket.
20784 */
20785 if (con->bucket == NULL((void*)0))
20786 con->bucket = rootBucket;
20787
20788 /* TODO:
20789 * SPEC (src-redefine):
20790 * (6.2) "If it has no such self-reference, then all of the
20791 * following must be true:"
20792
20793 * (6.2.2) The {model group} of the model group definition which
20794 * corresponds to it per XML Representation of Model Group
20795 * Definition Schema Components ($3.7.2) must be a `valid
20796 * restriction` of the {model group} of that model group definition
20797 * in I, as defined in Particle Valid (Restriction) ($3.9.6)."
20798 */
20799 xmlSchemaCheckSRCRedefineFirst(pctxt);
20800
20801 /*
20802 * Add global components to the schemata's hash tables.
20803 */
20804 xmlSchemaAddComponents(pctxt, rootBucket);
20805
20806 pctxt->ctxtType = NULL((void*)0);
20807 items = (xmlSchemaTreeItemPtr *) con->pending->items;
20808 nbItems = con->pending->nbItems;
20809 /*
20810 * Now that we have parsed *all* the schema document(s) and converted
20811 * them to schema components, we can resolve references, apply component
20812 * constraints, create the FSA from the content model, etc.
20813 */
20814 /*
20815 * Resolve references of..
20816 *
20817 * 1. element declarations:
20818 * - the type definition
20819 * - the substitution group affiliation
20820 * 2. simple/complex types:
20821 * - the base type definition
20822 * - the memberTypes of union types
20823 * - the itemType of list types
20824 * 3. attributes declarations and attribute uses:
20825 * - the type definition
20826 * - if an attribute use, then the attribute declaration
20827 * 4. attribute group references:
20828 * - the attribute group definition
20829 * 5. particles:
20830 * - the term of the particle (e.g. a model group)
20831 * 6. IDC key-references:
20832 * - the referenced IDC 'key' or 'unique' definition
20833 * 7. Attribute prohibitions which had a "ref" attribute.
20834 */
20835 for (i = 0; i < nbItems; i++) {
20836 item = items[i];
20837 switch (item->type) {
20838 case XML_SCHEMA_TYPE_ELEMENT:
20839 xmlSchemaResolveElementReferences(
20840 (xmlSchemaElementPtr) item, pctxt);
20841 FIXHFAILUREif (pctxt->err == XML_SCHEMAP_INTERNAL) goto exit_failure;;
20842 break;
20843 case XML_SCHEMA_TYPE_COMPLEX:
20844 case XML_SCHEMA_TYPE_SIMPLE:
20845 xmlSchemaResolveTypeReferences(
20846 (xmlSchemaTypePtr) item, pctxt);
20847 FIXHFAILUREif (pctxt->err == XML_SCHEMAP_INTERNAL) goto exit_failure;;
20848 break;
20849 case XML_SCHEMA_TYPE_ATTRIBUTE:
20850 xmlSchemaResolveAttrTypeReferences(
20851 (xmlSchemaAttributePtr) item, pctxt);
20852 FIXHFAILUREif (pctxt->err == XML_SCHEMAP_INTERNAL) goto exit_failure;;
20853 break;
20854 case XML_SCHEMA_TYPE_ATTRIBUTE_USE:
20855 xmlSchemaResolveAttrUseReferences(
20856 (xmlSchemaAttributeUsePtr) item, pctxt);
20857 FIXHFAILUREif (pctxt->err == XML_SCHEMAP_INTERNAL) goto exit_failure;;
20858 break;
20859 case XML_SCHEMA_EXTRA_QNAMEREF:
20860 if ((WXS_QNAME_CAST(xmlSchemaQNameRefPtr) item)->itemType ==
20861 XML_SCHEMA_TYPE_ATTRIBUTEGROUP)
20862 {
20863 xmlSchemaResolveAttrGroupReferences(
20864 WXS_QNAME_CAST(xmlSchemaQNameRefPtr) item, pctxt);
20865 }
20866 FIXHFAILUREif (pctxt->err == XML_SCHEMAP_INTERNAL) goto exit_failure;;
20867 break;
20868 case XML_SCHEMA_TYPE_SEQUENCE:
20869 case XML_SCHEMA_TYPE_CHOICE:
20870 case XML_SCHEMA_TYPE_ALL:
20871 xmlSchemaResolveModelGroupParticleReferences(pctxt,
20872 WXS_MODEL_GROUP_CAST(xmlSchemaModelGroupPtr) item);
20873 FIXHFAILUREif (pctxt->err == XML_SCHEMAP_INTERNAL) goto exit_failure;;
20874 break;
20875 case XML_SCHEMA_TYPE_IDC_KEY:
20876 case XML_SCHEMA_TYPE_IDC_UNIQUE:
20877 case XML_SCHEMA_TYPE_IDC_KEYREF:
20878 xmlSchemaResolveIDCKeyReferences(
20879 (xmlSchemaIDCPtr) item, pctxt);
20880 FIXHFAILUREif (pctxt->err == XML_SCHEMAP_INTERNAL) goto exit_failure;;
20881 break;
20882 case XML_SCHEMA_EXTRA_ATTR_USE_PROHIB:
20883 /*
20884 * Handle attribute prohibition which had a
20885 * "ref" attribute.
20886 */
20887 xmlSchemaResolveAttrUseProhibReferences(
20888 WXS_ATTR_PROHIB_CAST(xmlSchemaAttributeUseProhibPtr) item, pctxt);
20889 FIXHFAILUREif (pctxt->err == XML_SCHEMAP_INTERNAL) goto exit_failure;;
20890 break;
20891 default:
20892 break;
20893 }
20894 }
20895 if (pctxt->nberrors != 0)
20896 goto exit_error;
20897
20898 /*
20899 * Now that all references are resolved we
20900 * can check for circularity of...
20901 * 1. the base axis of type definitions
20902 * 2. nested model group definitions
20903 * 3. nested attribute group definitions
20904 * TODO: check for circular substitution groups.
20905 */
20906 for (i = 0; i < nbItems; i++) {
20907 item = items[i];
20908 /*
20909 * Let's better stop on the first error here.
20910 */
20911 switch (item->type) {
20912 case XML_SCHEMA_TYPE_COMPLEX:
20913 case XML_SCHEMA_TYPE_SIMPLE:
20914 xmlSchemaCheckTypeDefCircular(
20915 (xmlSchemaTypePtr) item, pctxt);
20916 FIXHFAILUREif (pctxt->err == XML_SCHEMAP_INTERNAL) goto exit_failure;;
20917 if (pctxt->nberrors != 0)
20918 goto exit_error;
20919 break;
20920 case XML_SCHEMA_TYPE_GROUP:
20921 xmlSchemaCheckGroupDefCircular(
20922 (xmlSchemaModelGroupDefPtr) item, pctxt);
20923 FIXHFAILUREif (pctxt->err == XML_SCHEMAP_INTERNAL) goto exit_failure;;
20924 if (pctxt->nberrors != 0)
20925 goto exit_error;
20926 break;
20927 case XML_SCHEMA_TYPE_ATTRIBUTEGROUP:
20928 xmlSchemaCheckAttrGroupCircular(
20929 (xmlSchemaAttributeGroupPtr) item, pctxt);
20930 FIXHFAILUREif (pctxt->err == XML_SCHEMAP_INTERNAL) goto exit_failure;;
20931 if (pctxt->nberrors != 0)
20932 goto exit_error;
20933 break;
20934 default:
20935 break;
20936 }
20937 }
20938 if (pctxt->nberrors != 0)
20939 goto exit_error;
20940 /*
20941 * Model group definition references:
20942 * Such a reference is reflected by a particle at the component
20943 * level. Until now the 'term' of such particles pointed
20944 * to the model group definition; this was done, in order to
20945 * ease circularity checks. Now we need to set the 'term' of
20946 * such particles to the model group of the model group definition.
20947 */
20948 for (i = 0; i < nbItems; i++) {
20949 item = items[i];
20950 switch (item->type) {
20951 case XML_SCHEMA_TYPE_SEQUENCE:
20952 case XML_SCHEMA_TYPE_CHOICE:
20953 xmlSchemaModelGroupToModelGroupDefFixup(pctxt,
20954 WXS_MODEL_GROUP_CAST(xmlSchemaModelGroupPtr) item);
20955 break;
20956 default:
20957 break;
20958 }
20959 }
20960 if (pctxt->nberrors != 0)
20961 goto exit_error;
20962 /*
20963 * Expand attribute group references of attribute group definitions.
20964 */
20965 for (i = 0; i < nbItems; i++) {
20966 item = items[i];
20967 switch (item->type) {
20968 case XML_SCHEMA_TYPE_ATTRIBUTEGROUP:
20969 if ((! WXS_ATTR_GROUP_EXPANDED(item)(((xmlSchemaAttributeGroupPtr) (item))->flags & 1 <<
0)
) &&
20970 WXS_ATTR_GROUP_HAS_REFS(item)(((xmlSchemaAttributeGroupPtr) (item))->flags & 1 <<
4)
)
20971 {
20972 xmlSchemaAttributeGroupExpandRefs(pctxt,
20973 WXS_ATTR_GROUP_CAST(xmlSchemaAttributeGroupPtr) item);
20974 FIXHFAILUREif (pctxt->err == XML_SCHEMAP_INTERNAL) goto exit_failure;;
20975 }
20976 break;
20977 default:
20978 break;
20979 }
20980 }
20981 if (pctxt->nberrors != 0)
20982 goto exit_error;
20983 /*
20984 * First compute the variety of simple types. This is needed as
20985 * a separate step, since otherwise we won't be able to detect
20986 * circular union types in all cases.
20987 */
20988 for (i = 0; i < nbItems; i++) {
20989 item = items[i];
20990 switch (item->type) {
20991 case XML_SCHEMA_TYPE_SIMPLE:
20992 if (WXS_IS_TYPE_NOT_FIXED_1((xmlSchemaTypePtr) item)((((xmlSchemaTypePtr) item)->type != XML_SCHEMA_TYPE_BASIC
) && ((((xmlSchemaTypePtr) item)->flags & 1 <<
29) == 0))
) {
20993 xmlSchemaFixupSimpleTypeStageOne(pctxt,
20994 (xmlSchemaTypePtr) item);
20995 FIXHFAILUREif (pctxt->err == XML_SCHEMAP_INTERNAL) goto exit_failure;;
20996 }
20997 break;
20998 default:
20999 break;
21000 }
21001 }
21002 if (pctxt->nberrors != 0)
21003 goto exit_error;
21004 /*
21005 * Detect circular union types. Note that this needs the variety to
21006 * be already computed.
21007 */
21008 for (i = 0; i < nbItems; i++) {
21009 item = items[i];
21010 switch (item->type) {
21011 case XML_SCHEMA_TYPE_SIMPLE:
21012 if (((xmlSchemaTypePtr) item)->memberTypes != NULL((void*)0)) {
21013 xmlSchemaCheckUnionTypeDefCircular(pctxt,
21014 (xmlSchemaTypePtr) item);
21015 FIXHFAILUREif (pctxt->err == XML_SCHEMAP_INTERNAL) goto exit_failure;;
21016 }
21017 break;
21018 default:
21019 break;
21020 }
21021 }
21022 if (pctxt->nberrors != 0)
21023 goto exit_error;
21024
21025 /*
21026 * Do the complete type fixup for simple types.
21027 */
21028 for (i = 0; i < nbItems; i++) {
21029 item = items[i];
21030 switch (item->type) {
21031 case XML_SCHEMA_TYPE_SIMPLE:
21032 if (WXS_IS_TYPE_NOT_FIXED(WXS_TYPE_CAST item)((((xmlSchemaTypePtr) item)->type != XML_SCHEMA_TYPE_BASIC
) && ((((xmlSchemaTypePtr) item)->flags & 1 <<
22) == 0))
) {
21033 xmlSchemaFixupSimpleTypeStageTwo(pctxt, WXS_TYPE_CAST(xmlSchemaTypePtr) item);
21034 FIXHFAILUREif (pctxt->err == XML_SCHEMAP_INTERNAL) goto exit_failure;;
21035 }
21036 break;
21037 default:
21038 break;
21039 }
21040 }
21041 if (pctxt->nberrors != 0)
21042 goto exit_error;
21043 /*
21044 * At this point we need build and check all simple types.
21045 */
21046 /*
21047 * Apply constraints for attribute declarations.
21048 */
21049 for (i = 0; i < nbItems; i++) {
21050 item = items[i];
21051 switch (item->type) {
21052 case XML_SCHEMA_TYPE_ATTRIBUTE:
21053 xmlSchemaCheckAttrPropsCorrect(pctxt, WXS_ATTR_CAST(xmlSchemaAttributePtr) item);
21054 FIXHFAILUREif (pctxt->err == XML_SCHEMAP_INTERNAL) goto exit_failure;;
21055 break;
21056 default:
21057 break;
21058 }
21059 }
21060 if (pctxt->nberrors != 0)
21061 goto exit_error;
21062 /*
21063 * Apply constraints for attribute uses.
21064 */
21065 for (i = 0; i < nbItems; i++) {
21066 item = items[i];
21067 switch (item->type) {
21068 case XML_SCHEMA_TYPE_ATTRIBUTE_USE:
21069 if (((xmlSchemaAttributeUsePtr)item)->defValue != NULL((void*)0)) {
21070 xmlSchemaCheckAttrUsePropsCorrect(pctxt,
21071 WXS_ATTR_USE_CAST(xmlSchemaAttributeUsePtr) item);
21072 FIXHFAILUREif (pctxt->err == XML_SCHEMAP_INTERNAL) goto exit_failure;;
21073 }
21074 break;
21075 default:
21076 break;
21077 }
21078 }
21079 if (pctxt->nberrors != 0)
21080 goto exit_error;
21081
21082 /*
21083 * Apply constraints for attribute group definitions.
21084 */
21085 for (i = 0; i < nbItems; i++) {
21086 item = items[i];
21087 switch (item->type) {
21088 case XML_SCHEMA_TYPE_ATTRIBUTEGROUP:
21089 if (( (WXS_ATTR_GROUP_CAST(xmlSchemaAttributeGroupPtr) item)->attrUses != NULL((void*)0)) &&
21090 ( (WXS_LIST_CAST(xmlSchemaItemListPtr) (WXS_ATTR_GROUP_CAST(xmlSchemaAttributeGroupPtr) item)->attrUses)->nbItems > 1))
21091 {
21092 xmlSchemaCheckAGPropsCorrect(pctxt, WXS_ATTR_GROUP_CAST(xmlSchemaAttributeGroupPtr) item);
21093 FIXHFAILUREif (pctxt->err == XML_SCHEMAP_INTERNAL) goto exit_failure;;
21094 }
21095 break;
21096 default:
21097 break;
21098 }
21099 }
21100 if (pctxt->nberrors != 0)
21101 goto exit_error;
21102
21103 /*
21104 * Apply constraints for redefinitions.
21105 */
21106 if (WXS_CONSTRUCTOR(pctxt)(pctxt)->constructor->redefs != NULL((void*)0))
21107 xmlSchemaCheckSRCRedefineSecond(pctxt);
21108 if (pctxt->nberrors != 0)
21109 goto exit_error;
21110
21111 /*
21112 * Complex types are built and checked.
21113 */
21114 for (i = 0; i < nbItems; i++) {
21115 item = con->pending->items[i];
21116 switch (item->type) {
21117 case XML_SCHEMA_TYPE_COMPLEX:
21118 if (WXS_IS_TYPE_NOT_FIXED(WXS_TYPE_CAST item)((((xmlSchemaTypePtr) item)->type != XML_SCHEMA_TYPE_BASIC
) && ((((xmlSchemaTypePtr) item)->flags & 1 <<
22) == 0))
) {
21119 xmlSchemaFixupComplexType(pctxt, WXS_TYPE_CAST(xmlSchemaTypePtr) item);
21120 FIXHFAILUREif (pctxt->err == XML_SCHEMAP_INTERNAL) goto exit_failure;;
21121 }
21122 break;
21123 default:
21124 break;
21125 }
21126 }
21127 if (pctxt->nberrors != 0)
21128 goto exit_error;
21129
21130 /*
21131 * The list could have changed, since xmlSchemaFixupComplexType()
21132 * will create particles and model groups in some cases.
21133 */
21134 items = (xmlSchemaTreeItemPtr *) con->pending->items;
21135 nbItems = con->pending->nbItems;
21136
21137 /*
21138 * Apply some constraints for element declarations.
21139 */
21140 for (i = 0; i < nbItems; i++) {
21141 item = items[i];
21142 switch (item->type) {
21143 case XML_SCHEMA_TYPE_ELEMENT:
21144 elemDecl = (xmlSchemaElementPtr) item;
21145
21146 if ((elemDecl->flags & XML_SCHEMAS_ELEM_INTERNAL_CHECKED1 << 18) == 0)
21147 {
21148 xmlSchemaCheckElementDeclComponent(
21149 (xmlSchemaElementPtr) elemDecl, pctxt);
21150 FIXHFAILUREif (pctxt->err == XML_SCHEMAP_INTERNAL) goto exit_failure;;
21151 }
21152
21153#ifdef WXS_ELEM_DECL_CONS_ENABLED
21154 /*
21155 * Schema Component Constraint: Element Declarations Consistent
21156 * Apply this constraint to local types of element declarations.
21157 */
21158 if ((WXS_ELEM_TYPEDEF(elemDecl)(elemDecl)->subtypes != NULL((void*)0)) &&
21159 (WXS_IS_COMPLEX(WXS_ELEM_TYPEDEF(elemDecl))((((elemDecl)->subtypes)->type == XML_SCHEMA_TYPE_COMPLEX
) || (((elemDecl)->subtypes)->builtInType == XML_SCHEMAS_ANYTYPE
))
) &&
21160 (WXS_TYPE_IS_LOCAL(WXS_ELEM_TYPEDEF(elemDecl))((((elemDecl)->subtypes)->flags & 1 << 3) == 0
)
))
21161 {
21162 xmlSchemaCheckElementDeclConsistent(pctxt,
21163 WXS_BASIC_CAST(xmlSchemaBasicItemPtr) elemDecl,
21164 WXS_TYPE_PARTICLE(WXS_ELEM_TYPEDEF(elemDecl))(xmlSchemaParticlePtr) ((elemDecl)->subtypes)->subtypes,
21165 NULL((void*)0), NULL((void*)0), 0);
21166 }
21167#endif
21168 break;
21169 default:
21170 break;
21171 }
21172 }
21173 if (pctxt->nberrors != 0)
21174 goto exit_error;
21175
21176 /*
21177 * Finally we can build the automaton from the content model of
21178 * complex types.
21179 */
21180
21181 for (i = 0; i < nbItems; i++) {
21182 item = items[i];
21183 switch (item->type) {
21184 case XML_SCHEMA_TYPE_COMPLEX:
21185 xmlSchemaBuildContentModel((xmlSchemaTypePtr) item, pctxt);
21186 /* FIXHFAILURE; */
21187 break;
21188 default:
21189 break;
21190 }
21191 }
21192 if (pctxt->nberrors != 0)
21193 goto exit_error;
21194 /*
21195 * URGENT TODO: cos-element-consistent
21196 */
21197 goto exit;
21198
21199exit_error:
21200 ret = pctxt->err;
21201 goto exit;
21202
21203exit_failure:
21204 ret = -1;
21205
21206exit:
21207 /*
21208 * Reset the constructor. This is needed for XSI acquisition, since
21209 * those items will be processed over and over again for every XSI
21210 * if not cleared here.
21211 */
21212 con->bucket = oldbucket;
21213 con->pending->nbItems = 0;
21214 if (con->substGroups != NULL((void*)0)) {
21215 xmlHashFree(con->substGroups, xmlSchemaSubstGroupFreeEntry);
21216 con->substGroups = NULL((void*)0);
21217 }
21218 if (con->redefs != NULL((void*)0)) {
21219 xmlSchemaRedefListFree(con->redefs);
21220 con->redefs = NULL((void*)0);
21221 }
21222 return(ret);
21223}
21224/**
21225 * xmlSchemaParse:
21226 * @ctxt: a schema validation context
21227 *
21228 * parse a schema definition resource and build an internal
21229 * XML Schema structure which can be used to validate instances.
21230 *
21231 * Returns the internal XML Schema structure built from the resource or
21232 * NULL in case of error
21233 */
21234xmlSchemaPtr
21235xmlSchemaParse(xmlSchemaParserCtxtPtr ctxt)
21236{
21237 xmlSchemaPtr mainSchema = NULL((void*)0);
21238 xmlSchemaBucketPtr bucket = NULL((void*)0);
21239 int res;
21240
21241 /*
21242 * This one is used if the schema to be parsed was specified via
21243 * the API; i.e. not automatically by the validated instance document.
21244 */
21245
21246 if (xmlSchemaInitTypes() < 0)
21247 return (NULL((void*)0));
21248
21249 if (ctxt == NULL((void*)0))
21250 return (NULL((void*)0));
21251
21252 /* TODO: Init the context. Is this all we need?*/
21253 ctxt->nberrors = 0;
21254 ctxt->err = 0;
21255 ctxt->counter = 0;
21256
21257 /* Create the *main* schema. */
21258 mainSchema = xmlSchemaNewSchema(ctxt);
21259 if (mainSchema == NULL((void*)0))
21260 goto exit_failure;
21261 /*
21262 * Create the schema constructor.
21263 */
21264 if (ctxt->constructor == NULL((void*)0)) {
21265 ctxt->constructor = xmlSchemaConstructionCtxtCreate(ctxt->dict);
21266 if (ctxt->constructor == NULL((void*)0))
21267 goto exit_failure;
21268 /* Take ownership of the constructor to be able to free it. */
21269 ctxt->ownsConstructor = 1;
21270 }
21271 ctxt->constructor->mainSchema = mainSchema;
21272 /*
21273 * Locate and add the schema document.
21274 */
21275 res = xmlSchemaAddSchemaDoc(ctxt, XML_SCHEMA_SCHEMA_MAIN0,
21276 ctxt->URL, ctxt->doc, ctxt->buffer, ctxt->size, NULL((void*)0),
21277 NULL((void*)0), NULL((void*)0), &bucket);
21278 if (res == -1)
21279 goto exit_failure;
21280 if (res != 0)
21281 goto exit;
21282
21283 if (bucket == NULL((void*)0)) {
21284 /* TODO: Error code, actually we failed to *locate* the schema. */
21285 if (ctxt->URL)
21286 xmlSchemaCustomErr(ACTXT_CAST(xmlSchemaAbstractCtxtPtr) ctxt, XML_SCHEMAP_FAILED_LOAD,
21287 NULL((void*)0), NULL((void*)0),
21288 "Failed to locate the main schema resource at '%s'",
21289 ctxt->URL, NULL((void*)0));
21290 else
21291 xmlSchemaCustomErr(ACTXT_CAST(xmlSchemaAbstractCtxtPtr) ctxt, XML_SCHEMAP_FAILED_LOAD,
21292 NULL((void*)0), NULL((void*)0),
21293 "Failed to locate the main schema resource",
21294 NULL((void*)0), NULL((void*)0));
21295 goto exit;
21296 }
21297 /* Then do the parsing for good. */
21298 if (xmlSchemaParseNewDocWithContext(ctxt, mainSchema, bucket) == -1)
21299 goto exit_failure;
21300 if (ctxt->nberrors != 0)
21301 goto exit;
21302
21303 mainSchema->doc = bucket->doc;
21304 mainSchema->preserve = ctxt->preserve;
21305
21306 ctxt->schema = mainSchema;
21307
21308 if (xmlSchemaFixupComponents(ctxt, WXS_CONSTRUCTOR(ctxt)(ctxt)->constructor->mainBucket) == -1)
21309 goto exit_failure;
21310
21311 /*
21312 * TODO: This is not nice, since we cannot distinguish from the
21313 * result if there was an internal error or not.
21314 */
21315exit:
21316 if (ctxt->nberrors != 0) {
21317 if (mainSchema) {
21318 xmlSchemaFree(mainSchema);
21319 mainSchema = NULL((void*)0);
21320 }
21321 if (ctxt->constructor) {
21322 xmlSchemaConstructionCtxtFree(ctxt->constructor);
21323 ctxt->constructor = NULL((void*)0);
21324 ctxt->ownsConstructor = 0;
21325 }
21326 }
21327 ctxt->schema = NULL((void*)0);
21328 return(mainSchema);
21329exit_failure:
21330 /*
21331 * Quite verbose, but should catch internal errors, which were
21332 * not communicated.
21333 */
21334 if (mainSchema) {
21335 xmlSchemaFree(mainSchema);
21336 mainSchema = NULL((void*)0);
21337 }
21338 if (ctxt->constructor) {
21339 xmlSchemaConstructionCtxtFree(ctxt->constructor);
21340 ctxt->constructor = NULL((void*)0);
21341 ctxt->ownsConstructor = 0;
21342 }
21343 PERROR_INT2("xmlSchemaParse",xmlSchemaInternalErr((xmlSchemaAbstractCtxtPtr) ctxt, "xmlSchemaParse"
, "An internal error occurred");
21344 "An internal error occurred")xmlSchemaInternalErr((xmlSchemaAbstractCtxtPtr) ctxt, "xmlSchemaParse"
, "An internal error occurred");
;
21345 ctxt->schema = NULL((void*)0);
21346 return(NULL((void*)0));
21347}
21348
21349/**
21350 * xmlSchemaSetParserErrors:
21351 * @ctxt: a schema validation context
21352 * @err: the error callback
21353 * @warn: the warning callback
21354 * @ctx: contextual data for the callbacks
21355 *
21356 * Set the callback functions used to handle errors for a validation context
21357 */
21358void
21359xmlSchemaSetParserErrors(xmlSchemaParserCtxtPtr ctxt,
21360 xmlSchemaValidityErrorFunc err,
21361 xmlSchemaValidityWarningFunc warn, void *ctx)
21362{
21363 if (ctxt == NULL((void*)0))
21364 return;
21365 ctxt->error = err;
21366 ctxt->warning = warn;
21367 ctxt->errCtxt = ctx;
21368 if (ctxt->vctxt != NULL((void*)0))
21369 xmlSchemaSetValidErrors(ctxt->vctxt, err, warn, ctx);
21370}
21371
21372/**
21373 * xmlSchemaSetParserStructuredErrors:
21374 * @ctxt: a schema parser context
21375 * @serror: the structured error function
21376 * @ctx: the functions context
21377 *
21378 * Set the structured error callback
21379 */
21380void
21381xmlSchemaSetParserStructuredErrors(xmlSchemaParserCtxtPtr ctxt,
21382 xmlStructuredErrorFunc serror,
21383 void *ctx)
21384{
21385 if (ctxt == NULL((void*)0))
21386 return;
21387 ctxt->serror = serror;
21388 ctxt->errCtxt = ctx;
21389 if (ctxt->vctxt != NULL((void*)0))
21390 xmlSchemaSetValidStructuredErrors(ctxt->vctxt, serror, ctx);
21391}
21392
21393/**
21394 * xmlSchemaGetParserErrors:
21395 * @ctxt: a XMl-Schema parser context
21396 * @err: the error callback result
21397 * @warn: the warning callback result
21398 * @ctx: contextual data for the callbacks result
21399 *
21400 * Get the callback information used to handle errors for a parser context
21401 *
21402 * Returns -1 in case of failure, 0 otherwise
21403 */
21404int
21405xmlSchemaGetParserErrors(xmlSchemaParserCtxtPtr ctxt,
21406 xmlSchemaValidityErrorFunc * err,
21407 xmlSchemaValidityWarningFunc * warn, void **ctx)
21408{
21409 if (ctxt == NULL((void*)0))
21410 return(-1);
21411 if (err != NULL((void*)0))
21412 *err = ctxt->error;
21413 if (warn != NULL((void*)0))
21414 *warn = ctxt->warning;
21415 if (ctx != NULL((void*)0))
21416 *ctx = ctxt->errCtxt;
21417 return(0);
21418}
21419
21420/**
21421 * xmlSchemaFacetTypeToString:
21422 * @type: the facet type
21423 *
21424 * Convert the xmlSchemaTypeType to a char string.
21425 *
21426 * Returns the char string representation of the facet type if the
21427 * type is a facet and an "Internal Error" string otherwise.
21428 */
21429static const xmlChar *
21430xmlSchemaFacetTypeToString(xmlSchemaTypeType type)
21431{
21432 switch (type) {
21433 case XML_SCHEMA_FACET_PATTERN:
21434 return (BAD_CAST(xmlChar *) "pattern");
21435 case XML_SCHEMA_FACET_MAXEXCLUSIVE:
21436 return (BAD_CAST(xmlChar *) "maxExclusive");
21437 case XML_SCHEMA_FACET_MAXINCLUSIVE:
21438 return (BAD_CAST(xmlChar *) "maxInclusive");
21439 case XML_SCHEMA_FACET_MINEXCLUSIVE:
21440 return (BAD_CAST(xmlChar *) "minExclusive");
21441 case XML_SCHEMA_FACET_MININCLUSIVE:
21442 return (BAD_CAST(xmlChar *) "minInclusive");
21443 case XML_SCHEMA_FACET_WHITESPACE:
21444 return (BAD_CAST(xmlChar *) "whiteSpace");
21445 case XML_SCHEMA_FACET_ENUMERATION:
21446 return (BAD_CAST(xmlChar *) "enumeration");
21447 case XML_SCHEMA_FACET_LENGTH:
21448 return (BAD_CAST(xmlChar *) "length");
21449 case XML_SCHEMA_FACET_MAXLENGTH:
21450 return (BAD_CAST(xmlChar *) "maxLength");
21451 case XML_SCHEMA_FACET_MINLENGTH:
21452 return (BAD_CAST(xmlChar *) "minLength");
21453 case XML_SCHEMA_FACET_TOTALDIGITS:
21454 return (BAD_CAST(xmlChar *) "totalDigits");
21455 case XML_SCHEMA_FACET_FRACTIONDIGITS:
21456 return (BAD_CAST(xmlChar *) "fractionDigits");
21457 default:
21458 break;
21459 }
21460 return (BAD_CAST(xmlChar *) "Internal Error");
21461}
21462
21463static xmlSchemaWhitespaceValueType
21464xmlSchemaGetWhiteSpaceFacetValue(xmlSchemaTypePtr type)
21465{
21466 /*
21467 * The normalization type can be changed only for types which are derived
21468 * from xsd:string.
21469 */
21470 if (type->type == XML_SCHEMA_TYPE_BASIC) {
21471 /*
21472 * Note that we assume a whitespace of preserve for anySimpleType.
21473 */
21474 if ((type->builtInType == XML_SCHEMAS_STRING) ||
21475 (type->builtInType == XML_SCHEMAS_ANYSIMPLETYPE))
21476 return(XML_SCHEMA_WHITESPACE_PRESERVE);
21477 else if (type->builtInType == XML_SCHEMAS_NORMSTRING)
21478 return(XML_SCHEMA_WHITESPACE_REPLACE);
21479 else {
21480 /*
21481 * For all `atomic` datatypes other than string (and types `derived`
21482 * by `restriction` from it) the value of whiteSpace is fixed to
21483 * collapse
21484 * Note that this includes built-in list datatypes.
21485 */
21486 return(XML_SCHEMA_WHITESPACE_COLLAPSE);
21487 }
21488 } else if (WXS_IS_LIST(type)(type->flags & 1 << 6)) {
21489 /*
21490 * For list types the facet "whiteSpace" is fixed to "collapse".
21491 */
21492 return (XML_SCHEMA_WHITESPACE_COLLAPSE);
21493 } else if (WXS_IS_UNION(type)(type->flags & 1 << 7)) {
21494 return (XML_SCHEMA_WHITESPACE_UNKNOWN);
21495 } else if (WXS_IS_ATOMIC(type)(type->flags & 1 << 8)) {
21496 if (type->flags & XML_SCHEMAS_TYPE_WHITESPACE_PRESERVE1 << 24)
21497 return (XML_SCHEMA_WHITESPACE_PRESERVE);
21498 else if (type->flags & XML_SCHEMAS_TYPE_WHITESPACE_REPLACE1 << 25)
21499 return (XML_SCHEMA_WHITESPACE_REPLACE);
21500 else
21501 return (XML_SCHEMA_WHITESPACE_COLLAPSE);
21502 }
21503 return (-1);
21504}
21505
21506/************************************************************************
21507 * *
21508 * Simple type validation *
21509 * *
21510 ************************************************************************/
21511
21512
21513/************************************************************************
21514 * *
21515 * DOM Validation code *
21516 * *
21517 ************************************************************************/
21518
21519/**
21520 * xmlSchemaAssembleByLocation:
21521 * @pctxt: a schema parser context
21522 * @vctxt: a schema validation context
21523 * @schema: the existing schema
21524 * @node: the node that fired the assembling
21525 * @nsName: the namespace name of the new schema
21526 * @location: the location of the schema
21527 *
21528 * Expands an existing schema by an additional schema.
21529 *
21530 * Returns 0 if the new schema is correct, a positive error code
21531 * number otherwise and -1 in case of an internal or API error.
21532 */
21533static int
21534xmlSchemaAssembleByLocation(xmlSchemaValidCtxtPtr vctxt,
21535 xmlSchemaPtr schema,
21536 xmlNodePtr node,
21537 const xmlChar *nsName,
21538 const xmlChar *location)
21539{
21540 int ret = 0;
21541 xmlSchemaParserCtxtPtr pctxt;
21542 xmlSchemaBucketPtr bucket = NULL((void*)0);
21543
21544 if ((vctxt == NULL((void*)0)) || (schema == NULL((void*)0)))
21545 return (-1);
21546
21547 if (vctxt->pctxt == NULL((void*)0)) {
21548 VERROR_INT("xmlSchemaAssembleByLocation",xmlSchemaInternalErr((xmlSchemaAbstractCtxtPtr) vctxt, "xmlSchemaAssembleByLocation"
, "no parser context available");
21549 "no parser context available")xmlSchemaInternalErr((xmlSchemaAbstractCtxtPtr) vctxt, "xmlSchemaAssembleByLocation"
, "no parser context available");
;
21550 return(-1);
21551 }
21552 pctxt = vctxt->pctxt;
21553 if (pctxt->constructor == NULL((void*)0)) {
21554 PERROR_INT("xmlSchemaAssembleByLocation",xmlSchemaInternalErr((xmlSchemaAbstractCtxtPtr) pctxt, "xmlSchemaAssembleByLocation"
, "no constructor");
21555 "no constructor")xmlSchemaInternalErr((xmlSchemaAbstractCtxtPtr) pctxt, "xmlSchemaAssembleByLocation"
, "no constructor");
;
21556 return(-1);
21557 }
21558 /*
21559 * Acquire the schema document.
21560 */
21561 location = xmlSchemaBuildAbsoluteURI(pctxt->dict,
21562 location, node);
21563 /*
21564 * Note that we pass XML_SCHEMA_SCHEMA_IMPORT here;
21565 * the process will automatically change this to
21566 * XML_SCHEMA_SCHEMA_MAIN if it is the first schema document.
21567 */
21568 ret = xmlSchemaAddSchemaDoc(pctxt, XML_SCHEMA_SCHEMA_IMPORT1,
21569 location, NULL((void*)0), NULL((void*)0), 0, node, NULL((void*)0), nsName,
21570 &bucket);
21571 if (ret != 0)
21572 return(ret);
21573 if (bucket == NULL((void*)0)) {
21574 /*
21575 * Generate a warning that the document could not be located.
21576 */
21577 xmlSchemaCustomWarning(ACTXT_CAST(xmlSchemaAbstractCtxtPtr) vctxt, XML_SCHEMAV_MISC,
21578 node, NULL((void*)0),
21579 "The document at location '%s' could not be acquired",
21580 location, NULL((void*)0), NULL((void*)0));
21581 return(ret);
21582 }
21583 /*
21584 * The first located schema will be handled as if all other
21585 * schemas imported by XSI were imported by this first schema.
21586 */
21587 if ((bucket != NULL((void*)0)) &&
21588 (WXS_CONSTRUCTOR(pctxt)(pctxt)->constructor->bucket == NULL((void*)0)))
21589 WXS_CONSTRUCTOR(pctxt)(pctxt)->constructor->bucket = bucket;
21590 /*
21591 * TODO: Is this handled like an import? I.e. is it not an error
21592 * if the schema cannot be located?
21593 */
21594 if ((bucket == NULL((void*)0)) || (! CAN_PARSE_SCHEMA(bucket)(((bucket)->doc != ((void*)0)) && ((bucket)->parsed
== 0))
))
21595 return(0);
21596 /*
21597 * We will reuse the parser context for every schema imported
21598 * directly via XSI. So reset the context.
21599 */
21600 pctxt->nberrors = 0;
21601 pctxt->err = 0;
21602 pctxt->doc = bucket->doc;
21603
21604 ret = xmlSchemaParseNewDocWithContext(pctxt, schema, bucket);
21605 if (ret == -1) {
21606 pctxt->doc = NULL((void*)0);
21607 goto exit_failure;
21608 }
21609 /* Paranoid error channelling. */
21610 if ((ret == 0) && (pctxt->nberrors != 0))
21611 ret = pctxt->err;
21612 if (pctxt->nberrors == 0) {
21613 /*
21614 * Only bother to fixup pending components, if there was
21615 * no error yet.
21616 * For every XSI acquired schema (and its sub-schemata) we will
21617 * fixup the components.
21618 */
21619 xmlSchemaFixupComponents(pctxt, bucket);
21620 ret = pctxt->err;
21621 /*
21622 * Not nice, but we need somehow to channel the schema parser
21623 * error to the validation context.
21624 */
21625 if ((ret != 0) && (vctxt->err == 0))
21626 vctxt->err = ret;
21627 vctxt->nberrors += pctxt->nberrors;
21628 } else {
21629 /* Add to validation error sum. */
21630 vctxt->nberrors += pctxt->nberrors;
21631 }
21632 pctxt->doc = NULL((void*)0);
21633 return(ret);
21634exit_failure:
21635 pctxt->doc = NULL((void*)0);
21636 return (-1);
21637}
21638
21639static xmlSchemaAttrInfoPtr
21640xmlSchemaGetMetaAttrInfo(xmlSchemaValidCtxtPtr vctxt,
21641 int metaType)
21642{
21643 if (vctxt->nbAttrInfos == 0)
21644 return (NULL((void*)0));
21645 {
21646 int i;
21647 xmlSchemaAttrInfoPtr iattr;
21648
21649 for (i = 0; i < vctxt->nbAttrInfos; i++) {
21650 iattr = vctxt->attrInfos[i];
21651 if (iattr->metaType == metaType)
21652 return (iattr);
21653 }
21654
21655 }
21656 return (NULL((void*)0));
21657}
21658
21659/**
21660 * xmlSchemaAssembleByXSI:
21661 * @vctxt: a schema validation context
21662 *
21663 * Expands an existing schema by an additional schema using
21664 * the xsi:schemaLocation or xsi:noNamespaceSchemaLocation attribute
21665 * of an instance. If xsi:noNamespaceSchemaLocation is used, @noNamespace
21666 * must be set to 1.
21667 *
21668 * Returns 0 if the new schema is correct, a positive error code
21669 * number otherwise and -1 in case of an internal or API error.
21670 */
21671static int
21672xmlSchemaAssembleByXSI(xmlSchemaValidCtxtPtr vctxt)
21673{
21674 const xmlChar *cur, *end;
21675 const xmlChar *nsname = NULL((void*)0), *location;
21676 int ret = 0;
21677 xmlSchemaAttrInfoPtr iattr;
21678
21679 /*
21680 * Parse the value; we will assume an even number of values
21681 * to be given (this is how Xerces and XSV work).
21682 *
21683 * URGENT TODO: !! This needs to work for both
21684 * @noNamespaceSchemaLocation AND @schemaLocation on the same
21685 * element !!
21686 */
21687 iattr = xmlSchemaGetMetaAttrInfo(vctxt,
21688 XML_SCHEMA_ATTR_INFO_META_XSI_SCHEMA_LOC3);
21689 if (iattr == NULL((void*)0))
21690 iattr = xmlSchemaGetMetaAttrInfo(vctxt,
21691 XML_SCHEMA_ATTR_INFO_META_XSI_NO_NS_SCHEMA_LOC4);
21692 if (iattr == NULL((void*)0))
21693 return (0);
21694 cur = iattr->value;
21695 do {
21696 /*
21697 * TODO: Move the string parsing mechanism away from here.
21698 */
21699 if (iattr->metaType == XML_SCHEMA_ATTR_INFO_META_XSI_SCHEMA_LOC3) {
21700 /*
21701 * Get the namespace name.
21702 */
21703 while (IS_BLANK_CH(*cur)(((*cur) == 0x20) || ((0x9 <= (*cur)) && ((*cur) <=
0xa)) || ((*cur) == 0xd))
)
21704 cur++;
21705 end = cur;
21706 while ((*end != 0) && (!(IS_BLANK_CH(*end)(((*end) == 0x20) || ((0x9 <= (*end)) && ((*end) <=
0xa)) || ((*end) == 0xd))
)))
21707 end++;
21708 if (end == cur)
21709 break;
21710 /* TODO: Don't use the schema's dict. */
21711 nsname = xmlDictLookup(vctxt->schema->dict, cur, end - cur);
21712 cur = end;
21713 }
21714 /*
21715 * Get the URI.
21716 */
21717 while (IS_BLANK_CH(*cur)(((*cur) == 0x20) || ((0x9 <= (*cur)) && ((*cur) <=
0xa)) || ((*cur) == 0xd))
)
21718 cur++;
21719 end = cur;
21720 while ((*end != 0) && (!(IS_BLANK_CH(*end)(((*end) == 0x20) || ((0x9 <= (*end)) && ((*end) <=
0xa)) || ((*end) == 0xd))
)))
21721 end++;
21722 if (end == cur) {
21723 if (iattr->metaType ==
21724 XML_SCHEMA_ATTR_INFO_META_XSI_SCHEMA_LOC3)
21725 {
21726 /*
21727 * If using @schemaLocation then tuples are expected.
21728 * I.e. the namespace name *and* the document's URI.
21729 */
21730 xmlSchemaCustomWarning(ACTXT_CAST(xmlSchemaAbstractCtxtPtr) vctxt, XML_SCHEMAV_MISC,
21731 iattr->node, NULL((void*)0),
21732 "The value must consist of tuples: the target namespace "
21733 "name and the document's URI", NULL((void*)0), NULL((void*)0), NULL((void*)0));
21734 }
21735 break;
21736 }
21737 /* TODO: Don't use the schema's dict. */
21738 location = xmlDictLookup(vctxt->schema->dict, cur, end - cur);
21739 cur = end;
21740 ret = xmlSchemaAssembleByLocation(vctxt, vctxt->schema,
21741 iattr->node, nsname, location);
21742 if (ret == -1) {
21743 VERROR_INT("xmlSchemaAssembleByXSI",xmlSchemaInternalErr((xmlSchemaAbstractCtxtPtr) vctxt, "xmlSchemaAssembleByXSI"
, "assembling schemata");
21744 "assembling schemata")xmlSchemaInternalErr((xmlSchemaAbstractCtxtPtr) vctxt, "xmlSchemaAssembleByXSI"
, "assembling schemata");
;
21745 return (-1);
21746 }
21747 } while (*cur != 0);
21748 return (ret);
21749}
21750
21751static const xmlChar *
21752xmlSchemaLookupNamespace(xmlSchemaValidCtxtPtr vctxt,
21753 const xmlChar *prefix)
21754{
21755 if (vctxt->sax != NULL((void*)0)) {
21756 int i, j;
21757 xmlSchemaNodeInfoPtr inode;
21758
21759 for (i = vctxt->depth; i >= 0; i--) {
21760 if (vctxt->elemInfos[i]->nbNsBindings != 0) {
21761 inode = vctxt->elemInfos[i];
21762 for (j = 0; j < inode->nbNsBindings * 2; j += 2) {
21763 if (((prefix == NULL((void*)0)) &&
21764 (inode->nsBindings[j] == NULL((void*)0))) ||
21765 ((prefix != NULL((void*)0)) && xmlStrEqual(prefix,
21766 inode->nsBindings[j]))) {
21767
21768 /*
21769 * Note that the namespace bindings are already
21770 * in a string dict.
21771 */
21772 return (inode->nsBindings[j+1]);
21773 }
21774 }
21775 }
21776 }
21777 return (NULL((void*)0));
21778#ifdef LIBXML_READER_ENABLED
21779 } else if (vctxt->reader != NULL((void*)0)) {
21780 xmlChar *nsName;
21781
21782 nsName = xmlTextReaderLookupNamespace(vctxt->reader, prefix);
21783 if (nsName != NULL((void*)0)) {
21784 const xmlChar *ret;
21785
21786 ret = xmlDictLookup(vctxt->dict, nsName, -1);
21787 xmlFree(nsName);
21788 return (ret);
21789 } else
21790 return (NULL((void*)0));
21791#endif
21792 } else {
21793 xmlNsPtr ns;
21794
21795 if ((vctxt->inode->node == NULL((void*)0)) ||
21796 (vctxt->inode->node->doc == NULL((void*)0))) {
21797 VERROR_INT("xmlSchemaLookupNamespace",xmlSchemaInternalErr((xmlSchemaAbstractCtxtPtr) vctxt, "xmlSchemaLookupNamespace"
, "no node or node's doc available");
21798 "no node or node's doc available")xmlSchemaInternalErr((xmlSchemaAbstractCtxtPtr) vctxt, "xmlSchemaLookupNamespace"
, "no node or node's doc available");
;
21799 return (NULL((void*)0));
21800 }
21801 ns = xmlSearchNs(vctxt->inode->node->doc,
21802 vctxt->inode->node, prefix);
21803 if (ns != NULL((void*)0))
21804 return (ns->href);
21805 return (NULL((void*)0));
21806 }
21807}
21808
21809/*
21810* This one works on the schema of the validation context.
21811*/
21812static int
21813xmlSchemaValidateNotation(xmlSchemaValidCtxtPtr vctxt,
21814 xmlSchemaPtr schema,
21815 xmlNodePtr node,
21816 const xmlChar *value,
21817 xmlSchemaValPtr *val,
21818 int valNeeded)
21819{
21820 int ret;
21821
21822 if (vctxt && (vctxt->schema == NULL((void*)0))) {
21823 VERROR_INT("xmlSchemaValidateNotation",xmlSchemaInternalErr((xmlSchemaAbstractCtxtPtr) vctxt, "xmlSchemaValidateNotation"
, "a schema is needed on the validation context");
21824 "a schema is needed on the validation context")xmlSchemaInternalErr((xmlSchemaAbstractCtxtPtr) vctxt, "xmlSchemaValidateNotation"
, "a schema is needed on the validation context");
;
21825 return (-1);
21826 }
21827 ret = xmlValidateQName(value, 1);
21828 if (ret != 0)
21829 return (ret);
21830 {
21831 xmlChar *localName = NULL((void*)0);
21832 xmlChar *prefix = NULL((void*)0);
21833
21834 localName = xmlSplitQName2(value, &prefix);
21835 if (prefix != NULL((void*)0)) {
21836 const xmlChar *nsName = NULL((void*)0);
21837
21838 if (vctxt != NULL((void*)0))
21839 nsName = xmlSchemaLookupNamespace(vctxt, BAD_CAST(xmlChar *) prefix);
21840 else if (node != NULL((void*)0)) {
21841 xmlNsPtr ns = xmlSearchNs(node->doc, node, prefix);
21842 if (ns != NULL((void*)0))
21843 nsName = ns->href;
21844 } else {
21845 xmlFree(prefix);
21846 xmlFree(localName);
21847 return (1);
21848 }
21849 if (nsName == NULL((void*)0)) {
21850 xmlFree(prefix);
21851 xmlFree(localName);
21852 return (1);
21853 }
21854 if (xmlSchemaGetNotation(schema, localName, nsName) != NULL((void*)0)) {
21855 if ((valNeeded) && (val != NULL((void*)0))) {
21856 (*val) = xmlSchemaNewNOTATIONValue(xmlStrdup(localName),
21857 xmlStrdup(nsName));
21858 if (*val == NULL((void*)0))
21859 ret = -1;
21860 }
21861 } else
21862 ret = 1;
21863 xmlFree(prefix);
21864 xmlFree(localName);
21865 } else {
21866 if (xmlSchemaGetNotation(schema, value, NULL((void*)0)) != NULL((void*)0)) {
21867 if (valNeeded && (val != NULL((void*)0))) {
21868 (*val) = xmlSchemaNewNOTATIONValue(
21869 BAD_CAST(xmlChar *) xmlStrdup(value), NULL((void*)0));
21870 if (*val == NULL((void*)0))
21871 ret = -1;
21872 }
21873 } else
21874 return (1);
21875 }
21876 }
21877 return (ret);
21878}
21879
21880static int
21881xmlSchemaVAddNodeQName(xmlSchemaValidCtxtPtr vctxt,
21882 const xmlChar* lname,
21883 const xmlChar* nsname)
21884{
21885 int i;
21886
21887 lname = xmlDictLookup(vctxt->dict, lname, -1);
21888 if (lname == NULL((void*)0))
21889 return(-1);
21890 if (nsname != NULL((void*)0)) {
21891 nsname = xmlDictLookup(vctxt->dict, nsname, -1);
21892 if (nsname == NULL((void*)0))
21893 return(-1);
21894 }
21895 for (i = 0; i < vctxt->nodeQNames->nbItems; i += 2) {
21896 if ((vctxt->nodeQNames->items [i] == lname) &&
21897 (vctxt->nodeQNames->items[i +1] == nsname))
21898 /* Already there */
21899 return(i);
21900 }
21901 /* Add new entry. */
21902 i = vctxt->nodeQNames->nbItems;
21903 xmlSchemaItemListAdd(vctxt->nodeQNames, (void *) lname);
21904 xmlSchemaItemListAdd(vctxt->nodeQNames, (void *) nsname);
21905 return(i);
21906}
21907
21908/************************************************************************
21909 * *
21910 * Validation of identity-constraints (IDC) *
21911 * *
21912 ************************************************************************/
21913
21914/**
21915 * xmlSchemaAugmentIDC:
21916 * @idcDef: the IDC definition
21917 *
21918 * Creates an augmented IDC definition item.
21919 *
21920 * Returns the item, or NULL on internal errors.
21921 */
21922static void
21923xmlSchemaAugmentIDC(void *payload, void *data,
21924 const xmlChar *name ATTRIBUTE_UNUSED__attribute__((unused)))
21925{
21926 xmlSchemaIDCPtr idcDef = (xmlSchemaIDCPtr) payload;
21927 xmlSchemaValidCtxtPtr vctxt = (xmlSchemaValidCtxtPtr) data;
21928 xmlSchemaIDCAugPtr aidc;
21929
21930 aidc = (xmlSchemaIDCAugPtr) xmlMalloc(sizeof(xmlSchemaIDCAug));
21931 if (aidc == NULL((void*)0)) {
21932 xmlSchemaVErrMemory(vctxt,
21933 "xmlSchemaAugmentIDC: allocating an augmented IDC definition",
21934 NULL((void*)0));
21935 return;
21936 }
21937 aidc->keyrefDepth = -1;
21938 aidc->def = idcDef;
21939 aidc->next = NULL((void*)0);
21940 if (vctxt->aidcs == NULL((void*)0))
21941 vctxt->aidcs = aidc;
21942 else {
21943 aidc->next = vctxt->aidcs;
21944 vctxt->aidcs = aidc;
21945 }
21946 /*
21947 * Save if we have keyrefs at all.
21948 */
21949 if ((vctxt->hasKeyrefs == 0) &&
21950 (idcDef->type == XML_SCHEMA_TYPE_IDC_KEYREF))
21951 vctxt->hasKeyrefs = 1;
21952}
21953
21954/**
21955 * xmlSchemaAugmentImportedIDC:
21956 * @imported: the imported schema
21957 *
21958 * Creates an augmented IDC definition for the imported schema.
21959 */
21960static void
21961xmlSchemaAugmentImportedIDC(void *payload, void *data,
21962 const xmlChar *name ATTRIBUTE_UNUSED__attribute__((unused))) {
21963 xmlSchemaImportPtr imported = (xmlSchemaImportPtr) payload;
21964 xmlSchemaValidCtxtPtr vctxt = (xmlSchemaValidCtxtPtr) data;
21965 if (imported->schema->idcDef != NULL((void*)0)) {
21966 xmlHashScan(imported->schema->idcDef, xmlSchemaAugmentIDC, vctxt);
21967 }
21968}
21969
21970/**
21971 * xmlSchemaIDCNewBinding:
21972 * @idcDef: the IDC definition of this binding
21973 *
21974 * Creates a new IDC binding.
21975 *
21976 * Returns the new IDC binding, NULL on internal errors.
21977 */
21978static xmlSchemaPSVIIDCBindingPtr
21979xmlSchemaIDCNewBinding(xmlSchemaIDCPtr idcDef)
21980{
21981 xmlSchemaPSVIIDCBindingPtr ret;
21982
21983 ret = (xmlSchemaPSVIIDCBindingPtr) xmlMalloc(
21984 sizeof(xmlSchemaPSVIIDCBinding));
21985 if (ret == NULL((void*)0)) {
21986 xmlSchemaVErrMemory(NULL((void*)0),
21987 "allocating a PSVI IDC binding item", NULL((void*)0));
21988 return (NULL((void*)0));
21989 }
21990 memset(ret, 0, sizeof(xmlSchemaPSVIIDCBinding));
21991 ret->definition = idcDef;
21992 return (ret);
21993}
21994
21995/**
21996 * xmlSchemaIDCStoreNodeTableItem:
21997 * @vctxt: the WXS validation context
21998 * @item: the IDC node table item
21999 *
22000 * The validation context is used to store IDC node table items.
22001 * They are stored to avoid copying them if IDC node-tables are merged
22002 * with corresponding parent IDC node-tables (bubbling).
22003 *
22004 * Returns 0 if succeeded, -1 on internal errors.
22005 */
22006static int
22007xmlSchemaIDCStoreNodeTableItem(xmlSchemaValidCtxtPtr vctxt,
22008 xmlSchemaPSVIIDCNodePtr item)
22009{
22010 /*
22011 * Add to global list.
22012 */
22013 if (vctxt->idcNodes == NULL((void*)0)) {
22014 vctxt->idcNodes = (xmlSchemaPSVIIDCNodePtr *)
22015 xmlMalloc(20 * sizeof(xmlSchemaPSVIIDCNodePtr));
22016 if (vctxt->idcNodes == NULL((void*)0)) {
22017 xmlSchemaVErrMemory(vctxt,
22018 "allocating the IDC node table item list", NULL((void*)0));
22019 return (-1);
22020 }
22021 vctxt->sizeIdcNodes = 20;
22022 } else if (vctxt->sizeIdcNodes <= vctxt->nbIdcNodes) {
22023 vctxt->sizeIdcNodes *= 2;
22024 vctxt->idcNodes = (xmlSchemaPSVIIDCNodePtr *)
22025 xmlRealloc(vctxt->idcNodes, vctxt->sizeIdcNodes *
22026 sizeof(xmlSchemaPSVIIDCNodePtr));
22027 if (vctxt->idcNodes == NULL((void*)0)) {
22028 xmlSchemaVErrMemory(vctxt,
22029 "re-allocating the IDC node table item list", NULL((void*)0));
22030 return (-1);
22031 }
22032 }
22033 vctxt->idcNodes[vctxt->nbIdcNodes++] = item;
22034
22035 return (0);
22036}
22037
22038/**
22039 * xmlSchemaIDCStoreKey:
22040 * @vctxt: the WXS validation context
22041 * @item: the IDC key
22042 *
22043 * The validation context is used to store an IDC key.
22044 *
22045 * Returns 0 if succeeded, -1 on internal errors.
22046 */
22047static int
22048xmlSchemaIDCStoreKey(xmlSchemaValidCtxtPtr vctxt,
22049 xmlSchemaPSVIIDCKeyPtr key)
22050{
22051 /*
22052 * Add to global list.
22053 */
22054 if (vctxt->idcKeys == NULL((void*)0)) {
22055 vctxt->idcKeys = (xmlSchemaPSVIIDCKeyPtr *)
22056 xmlMalloc(40 * sizeof(xmlSchemaPSVIIDCKeyPtr));
22057 if (vctxt->idcKeys == NULL((void*)0)) {
22058 xmlSchemaVErrMemory(vctxt,
22059 "allocating the IDC key storage list", NULL((void*)0));
22060 return (-1);
22061 }
22062 vctxt->sizeIdcKeys = 40;
22063 } else if (vctxt->sizeIdcKeys <= vctxt->nbIdcKeys) {
22064 vctxt->sizeIdcKeys *= 2;
22065 vctxt->idcKeys = (xmlSchemaPSVIIDCKeyPtr *)
22066 xmlRealloc(vctxt->idcKeys, vctxt->sizeIdcKeys *
22067 sizeof(xmlSchemaPSVIIDCKeyPtr));
22068 if (vctxt->idcKeys == NULL((void*)0)) {
22069 xmlSchemaVErrMemory(vctxt,
22070 "re-allocating the IDC key storage list", NULL((void*)0));
22071 return (-1);
22072 }
22073 }
22074 vctxt->idcKeys[vctxt->nbIdcKeys++] = key;
22075
22076 return (0);
22077}
22078
22079/**
22080 * xmlSchemaIDCAppendNodeTableItem:
22081 * @bind: the IDC binding
22082 * @ntItem: the node-table item
22083 *
22084 * Appends the IDC node-table item to the binding.
22085 *
22086 * Returns 0 on success and -1 on internal errors.
22087 */
22088static int
22089xmlSchemaIDCAppendNodeTableItem(xmlSchemaPSVIIDCBindingPtr bind,
22090 xmlSchemaPSVIIDCNodePtr ntItem)
22091{
22092 if (bind->nodeTable == NULL((void*)0)) {
22093 bind->sizeNodes = 10;
22094 bind->nodeTable = (xmlSchemaPSVIIDCNodePtr *)
22095 xmlMalloc(10 * sizeof(xmlSchemaPSVIIDCNodePtr));
22096 if (bind->nodeTable == NULL((void*)0)) {
22097 xmlSchemaVErrMemory(NULL((void*)0),
22098 "allocating an array of IDC node-table items", NULL((void*)0));
22099 return(-1);
22100 }
22101 } else if (bind->sizeNodes <= bind->nbNodes) {
22102 bind->sizeNodes *= 2;
22103 bind->nodeTable = (xmlSchemaPSVIIDCNodePtr *)
22104 xmlRealloc(bind->nodeTable, bind->sizeNodes *
22105 sizeof(xmlSchemaPSVIIDCNodePtr));
22106 if (bind->nodeTable == NULL((void*)0)) {
22107 xmlSchemaVErrMemory(NULL((void*)0),
22108 "re-allocating an array of IDC node-table items", NULL((void*)0));
22109 return(-1);
22110 }
22111 }
22112 bind->nodeTable[bind->nbNodes++] = ntItem;
22113 return(0);
22114}
22115
22116/**
22117 * xmlSchemaIDCAcquireBinding:
22118 * @vctxt: the WXS validation context
22119 * @matcher: the IDC matcher
22120 *
22121 * Looks up an PSVI IDC binding, for the IDC definition and
22122 * of the given matcher. If none found, a new one is created
22123 * and added to the IDC table.
22124 *
22125 * Returns an IDC binding or NULL on internal errors.
22126 */
22127static xmlSchemaPSVIIDCBindingPtr
22128xmlSchemaIDCAcquireBinding(xmlSchemaValidCtxtPtr vctxt,
22129 xmlSchemaIDCMatcherPtr matcher)
22130{
22131 xmlSchemaNodeInfoPtr ielem;
22132
22133 ielem = vctxt->elemInfos[matcher->depth];
22134
22135 if (ielem->idcTable == NULL((void*)0)) {
22136 ielem->idcTable = xmlSchemaIDCNewBinding(matcher->aidc->def);
22137 if (ielem->idcTable == NULL((void*)0))
22138 return (NULL((void*)0));
22139 return(ielem->idcTable);
22140 } else {
22141 xmlSchemaPSVIIDCBindingPtr bind = NULL((void*)0);
22142
22143 bind = ielem->idcTable;
22144 do {
22145 if (bind->definition == matcher->aidc->def)
22146 return(bind);
22147 if (bind->next == NULL((void*)0)) {
22148 bind->next = xmlSchemaIDCNewBinding(matcher->aidc->def);
22149 if (bind->next == NULL((void*)0))
22150 return (NULL((void*)0));
22151 return(bind->next);
22152 }
22153 bind = bind->next;
22154 } while (bind != NULL((void*)0));
22155 }
22156 return (NULL((void*)0));
22157}
22158
22159static xmlSchemaItemListPtr
22160xmlSchemaIDCAcquireTargetList(xmlSchemaValidCtxtPtr vctxt ATTRIBUTE_UNUSED__attribute__((unused)),
22161 xmlSchemaIDCMatcherPtr matcher)
22162{
22163 if (matcher->targets == NULL((void*)0))
22164 matcher->targets = xmlSchemaItemListCreate();
22165 return(matcher->targets);
22166}
22167
22168/**
22169 * xmlSchemaIDCFreeKey:
22170 * @key: the IDC key
22171 *
22172 * Frees an IDC key together with its compiled value.
22173 */
22174static void
22175xmlSchemaIDCFreeKey(xmlSchemaPSVIIDCKeyPtr key)
22176{
22177 if (key->val != NULL((void*)0))
22178 xmlSchemaFreeValue(key->val);
22179 xmlFree(key);
22180}
22181
22182/**
22183 * xmlSchemaIDCFreeBinding:
22184 *
22185 * Frees an IDC binding. Note that the node table-items
22186 * are not freed.
22187 */
22188static void
22189xmlSchemaIDCFreeBinding(xmlSchemaPSVIIDCBindingPtr bind)
22190{
22191 if (bind->nodeTable != NULL((void*)0))
22192 xmlFree(bind->nodeTable);
22193 if (bind->dupls != NULL((void*)0))
22194 xmlSchemaItemListFree(bind->dupls);
22195 xmlFree(bind);
22196}
22197
22198/**
22199 * xmlSchemaIDCFreeIDCTable:
22200 * @bind: the first IDC binding in the list
22201 *
22202 * Frees an IDC table, i.e. all the IDC bindings in the list.
22203 */
22204static void
22205xmlSchemaIDCFreeIDCTable(xmlSchemaPSVIIDCBindingPtr bind)
22206{
22207 xmlSchemaPSVIIDCBindingPtr prev;
22208
22209 while (bind != NULL((void*)0)) {
22210 prev = bind;
22211 bind = bind->next;
22212 xmlSchemaIDCFreeBinding(prev);
22213 }
22214}
22215
22216static void
22217xmlFreeIDCHashEntry (void *payload, const xmlChar *name ATTRIBUTE_UNUSED__attribute__((unused)))
22218{
22219 xmlIDCHashEntryPtr e = payload, n;
22220 while (e) {
22221 n = e->next;
22222 xmlFree(e);
22223 e = n;
22224 }
22225}
22226
22227/**
22228 * xmlSchemaIDCFreeMatcherList:
22229 * @matcher: the first IDC matcher in the list
22230 *
22231 * Frees a list of IDC matchers.
22232 */
22233static void
22234xmlSchemaIDCFreeMatcherList(xmlSchemaIDCMatcherPtr matcher)
22235{
22236 xmlSchemaIDCMatcherPtr next;
22237
22238 while (matcher != NULL((void*)0)) {
22239 next = matcher->next;
22240 if (matcher->keySeqs != NULL((void*)0)) {
22241 int i;
22242 for (i = 0; i < matcher->sizeKeySeqs; i++)
22243 if (matcher->keySeqs[i] != NULL((void*)0))
22244 xmlFree(matcher->keySeqs[i]);
22245 xmlFree(matcher->keySeqs);
22246 }
22247 if (matcher->targets != NULL((void*)0)) {
22248 if (matcher->idcType == XML_SCHEMA_TYPE_IDC_KEYREF) {
22249 int i;
22250 xmlSchemaPSVIIDCNodePtr idcNode;
22251 /*
22252 * Node-table items for keyrefs are not stored globally
22253 * to the validation context, since they are not bubbled.
22254 * We need to free them here.
22255 */
22256 for (i = 0; i < matcher->targets->nbItems; i++) {
22257 idcNode =
22258 (xmlSchemaPSVIIDCNodePtr) matcher->targets->items[i];
22259 xmlFree(idcNode->keys);
22260 xmlFree(idcNode);
22261 }
22262 }
22263 xmlSchemaItemListFree(matcher->targets);
22264 }
22265 if (matcher->htab != NULL((void*)0))
22266 xmlHashFree(matcher->htab, xmlFreeIDCHashEntry);
22267 xmlFree(matcher);
22268 matcher = next;
22269 }
22270}
22271
22272/**
22273 * xmlSchemaIDCReleaseMatcherList:
22274 * @vctxt: the WXS validation context
22275 * @matcher: the first IDC matcher in the list
22276 *
22277 * Caches a list of IDC matchers for reuse.
22278 */
22279static void
22280xmlSchemaIDCReleaseMatcherList(xmlSchemaValidCtxtPtr vctxt,
22281 xmlSchemaIDCMatcherPtr matcher)
22282{
22283 xmlSchemaIDCMatcherPtr next;
22284
22285 while (matcher != NULL((void*)0)) {
22286 next = matcher->next;
22287 if (matcher->keySeqs != NULL((void*)0)) {
22288 int i;
22289 /*
22290 * Don't free the array, but only the content.
22291 */
22292 for (i = 0; i < matcher->sizeKeySeqs; i++)
22293 if (matcher->keySeqs[i] != NULL((void*)0)) {
22294 xmlFree(matcher->keySeqs[i]);
22295 matcher->keySeqs[i] = NULL((void*)0);
22296 }
22297 }
22298 if (matcher->targets) {
22299 if (matcher->idcType == XML_SCHEMA_TYPE_IDC_KEYREF) {
22300 int i;
22301 xmlSchemaPSVIIDCNodePtr idcNode;
22302 /*
22303 * Node-table items for keyrefs are not stored globally
22304 * to the validation context, since they are not bubbled.
22305 * We need to free them here.
22306 */
22307 for (i = 0; i < matcher->targets->nbItems; i++) {
22308 idcNode =
22309 (xmlSchemaPSVIIDCNodePtr) matcher->targets->items[i];
22310 xmlFree(idcNode->keys);
22311 xmlFree(idcNode);
22312 }
22313 }
22314 xmlSchemaItemListFree(matcher->targets);
22315 matcher->targets = NULL((void*)0);
22316 }
22317 if (matcher->htab != NULL((void*)0)) {
22318 xmlHashFree(matcher->htab, xmlFreeIDCHashEntry);
22319 matcher->htab = NULL((void*)0);
22320 }
22321 matcher->next = NULL((void*)0);
22322 /*
22323 * Cache the matcher.
22324 */
22325 if (vctxt->idcMatcherCache != NULL((void*)0))
22326 matcher->nextCached = vctxt->idcMatcherCache;
22327 vctxt->idcMatcherCache = matcher;
22328
22329 matcher = next;
22330 }
22331}
22332
22333/**
22334 * xmlSchemaIDCAddStateObject:
22335 * @vctxt: the WXS validation context
22336 * @matcher: the IDC matcher
22337 * @sel: the XPath information
22338 * @parent: the parent "selector" state object if any
22339 * @type: "selector" or "field"
22340 *
22341 * Creates/reuses and activates state objects for the given
22342 * XPath information; if the XPath expression consists of unions,
22343 * multiple state objects are created for every unioned expression.
22344 *
22345 * Returns 0 on success and -1 on internal errors.
22346 */
22347static int
22348xmlSchemaIDCAddStateObject(xmlSchemaValidCtxtPtr vctxt,
22349 xmlSchemaIDCMatcherPtr matcher,
22350 xmlSchemaIDCSelectPtr sel,
22351 int type)
22352{
22353 xmlSchemaIDCStateObjPtr sto;
22354
22355 /*
22356 * Reuse the state objects from the pool.
22357 */
22358 if (vctxt->xpathStatePool != NULL((void*)0)) {
22359 sto = vctxt->xpathStatePool;
22360 vctxt->xpathStatePool = sto->next;
22361 sto->next = NULL((void*)0);
22362 } else {
22363 /*
22364 * Create a new state object.
22365 */
22366 sto = (xmlSchemaIDCStateObjPtr) xmlMalloc(sizeof(xmlSchemaIDCStateObj));
22367 if (sto == NULL((void*)0)) {
22368 xmlSchemaVErrMemory(NULL((void*)0),
22369 "allocating an IDC state object", NULL((void*)0));
22370 return (-1);
22371 }
22372 memset(sto, 0, sizeof(xmlSchemaIDCStateObj));
22373 }
22374 /*
22375 * Add to global list.
22376 */
22377 if (vctxt->xpathStates != NULL((void*)0))
22378 sto->next = vctxt->xpathStates;
22379 vctxt->xpathStates = sto;
22380
22381 /*
22382 * Free the old xpath validation context.
22383 */
22384 if (sto->xpathCtxt != NULL((void*)0))
22385 xmlFreeStreamCtxt((xmlStreamCtxtPtr) sto->xpathCtxt);
22386
22387 /*
22388 * Create a new XPath (pattern) validation context.
22389 */
22390 sto->xpathCtxt = (void *) xmlPatternGetStreamCtxt(
22391 (xmlPatternPtr) sel->xpathComp);
22392 if (sto->xpathCtxt == NULL((void*)0)) {
22393 VERROR_INT("xmlSchemaIDCAddStateObject",xmlSchemaInternalErr((xmlSchemaAbstractCtxtPtr) vctxt, "xmlSchemaIDCAddStateObject"
, "failed to create an XPath validation context");
22394 "failed to create an XPath validation context")xmlSchemaInternalErr((xmlSchemaAbstractCtxtPtr) vctxt, "xmlSchemaIDCAddStateObject"
, "failed to create an XPath validation context");
;
22395 return (-1);
22396 }
22397 sto->type = type;
22398 sto->depth = vctxt->depth;
22399 sto->matcher = matcher;
22400 sto->sel = sel;
22401 sto->nbHistory = 0;
22402
22403 return (0);
22404}
22405
22406/**
22407 * xmlSchemaXPathEvaluate:
22408 * @vctxt: the WXS validation context
22409 * @nodeType: the nodeType of the current node
22410 *
22411 * Evaluates all active XPath state objects.
22412 *
22413 * Returns the number of IC "field" state objects which resolved to
22414 * this node, 0 if none resolved and -1 on internal errors.
22415 */
22416static int
22417xmlSchemaXPathEvaluate(xmlSchemaValidCtxtPtr vctxt,
22418 xmlElementType nodeType)
22419{
22420 xmlSchemaIDCStateObjPtr sto, head = NULL((void*)0), first;
22421 int res, resolved = 0, depth = vctxt->depth;
22422
22423 if (vctxt->xpathStates == NULL((void*)0))
22424 return (0);
22425
22426 if (nodeType == XML_ATTRIBUTE_NODE)
22427 depth++;
22428 /*
22429 * Process all active XPath state objects.
22430 */
22431 first = vctxt->xpathStates;
22432 sto = first;
22433 while (sto != head) {
22434 if (nodeType == XML_ELEMENT_NODE)
22435 res = xmlStreamPush((xmlStreamCtxtPtr) sto->xpathCtxt,
22436 vctxt->inode->localName, vctxt->inode->nsName);
22437 else
22438 res = xmlStreamPushAttr((xmlStreamCtxtPtr) sto->xpathCtxt,
22439 vctxt->inode->localName, vctxt->inode->nsName);
22440
22441 if (res == -1) {
22442 VERROR_INT("xmlSchemaXPathEvaluate",xmlSchemaInternalErr((xmlSchemaAbstractCtxtPtr) vctxt, "xmlSchemaXPathEvaluate"
, "calling xmlStreamPush()");
22443 "calling xmlStreamPush()")xmlSchemaInternalErr((xmlSchemaAbstractCtxtPtr) vctxt, "xmlSchemaXPathEvaluate"
, "calling xmlStreamPush()");
;
22444 return (-1);
22445 }
22446 if (res == 0)
22447 goto next_sto;
22448 /*
22449 * Full match.
22450 */
22451 /*
22452 * Register a match in the state object history.
22453 */
22454 if (sto->history == NULL((void*)0)) {
22455 sto->history = (int *) xmlMalloc(5 * sizeof(int));
22456 if (sto->history == NULL((void*)0)) {
22457 xmlSchemaVErrMemory(NULL((void*)0),
22458 "allocating the state object history", NULL((void*)0));
22459 return(-1);
22460 }
22461 sto->sizeHistory = 5;
22462 } else if (sto->sizeHistory <= sto->nbHistory) {
22463 sto->sizeHistory *= 2;
22464 sto->history = (int *) xmlRealloc(sto->history,
22465 sto->sizeHistory * sizeof(int));
22466 if (sto->history == NULL((void*)0)) {
22467 xmlSchemaVErrMemory(NULL((void*)0),
22468 "re-allocating the state object history", NULL((void*)0));
22469 return(-1);
22470 }
22471 }
22472 sto->history[sto->nbHistory++] = depth;
22473
22474 if (sto->type == XPATH_STATE_OBJ_TYPE_IDC_SELECTOR1) {
22475 xmlSchemaIDCSelectPtr sel;
22476 /*
22477 * Activate state objects for the IDC fields of
22478 * the IDC selector.
22479 */
22480 sel = sto->matcher->aidc->def->fields;
22481 while (sel != NULL((void*)0)) {
22482 if (xmlSchemaIDCAddStateObject(vctxt, sto->matcher,
22483 sel, XPATH_STATE_OBJ_TYPE_IDC_FIELD2) == -1)
22484 return (-1);
22485 sel = sel->next;
22486 }
22487 } else if (sto->type == XPATH_STATE_OBJ_TYPE_IDC_FIELD2) {
22488 /*
22489 * An IDC key node was found by the IDC field.
22490 */
22491 /*
22492 * Notify that the character value of this node is
22493 * needed.
22494 */
22495 if (resolved == 0) {
22496 if ((vctxt->inode->flags &
22497 XML_SCHEMA_NODE_INFO_VALUE_NEEDED1<<4) == 0)
22498 vctxt->inode->flags |= XML_SCHEMA_NODE_INFO_VALUE_NEEDED1<<4;
22499 }
22500 resolved++;
22501 }
22502next_sto:
22503 if (sto->next == NULL((void*)0)) {
22504 /*
22505 * Evaluate field state objects created on this node as well.
22506 */
22507 head = first;
22508 sto = vctxt->xpathStates;
22509 } else
22510 sto = sto->next;
22511 }
22512 return (resolved);
22513}
22514
22515static const xmlChar *
22516xmlSchemaFormatIDCKeySequence_1(xmlSchemaValidCtxtPtr vctxt,
22517 xmlChar **buf,
22518 xmlSchemaPSVIIDCKeyPtr *seq,
22519 int count, int for_hash)
22520{
22521 int i, res;
22522 xmlChar *value = NULL((void*)0);
22523
22524 *buf = xmlStrdup(BAD_CAST(xmlChar *) "[");
22525 for (i = 0; i < count; i++) {
22526 *buf = xmlStrcat(*buf, BAD_CAST(xmlChar *) "'");
22527 if (!for_hash)
22528 res = xmlSchemaGetCanonValueWhtspExt(seq[i]->val,
22529 xmlSchemaGetWhiteSpaceFacetValue(seq[i]->type),
22530 &value);
22531 else {
22532 res = xmlSchemaGetCanonValueHash(seq[i]->val, &value);
22533 }
22534 if (res == 0)
22535 *buf = xmlStrcat(*buf, BAD_CAST(xmlChar *) value);
22536 else {
22537 VERROR_INT("xmlSchemaFormatIDCKeySequence",xmlSchemaInternalErr((xmlSchemaAbstractCtxtPtr) vctxt, "xmlSchemaFormatIDCKeySequence"
, "failed to compute a canonical value");
22538 "failed to compute a canonical value")xmlSchemaInternalErr((xmlSchemaAbstractCtxtPtr) vctxt, "xmlSchemaFormatIDCKeySequence"
, "failed to compute a canonical value");
;
22539 *buf = xmlStrcat(*buf, BAD_CAST(xmlChar *) "???");
22540 }
22541 if (i < count -1)
22542 *buf = xmlStrcat(*buf, BAD_CAST(xmlChar *) "', ");
22543 else
22544 *buf = xmlStrcat(*buf, BAD_CAST(xmlChar *) "'");
22545 if (value != NULL((void*)0)) {
22546 xmlFree(value);
22547 value = NULL((void*)0);
22548 }
22549 }
22550 *buf = xmlStrcat(*buf, BAD_CAST(xmlChar *) "]");
22551
22552 return (BAD_CAST(xmlChar *) *buf);
22553}
22554
22555static const xmlChar *
22556xmlSchemaFormatIDCKeySequence(xmlSchemaValidCtxtPtr vctxt,
22557 xmlChar **buf,
22558 xmlSchemaPSVIIDCKeyPtr *seq,
22559 int count)
22560{
22561 return xmlSchemaFormatIDCKeySequence_1(vctxt, buf, seq, count, 0);
22562}
22563
22564static const xmlChar *
22565xmlSchemaHashKeySequence(xmlSchemaValidCtxtPtr vctxt,
22566 xmlChar **buf,
22567 xmlSchemaPSVIIDCKeyPtr *seq,
22568 int count)
22569{
22570 return xmlSchemaFormatIDCKeySequence_1(vctxt, buf, seq, count, 1);
22571}
22572
22573/**
22574 * xmlSchemaXPathPop:
22575 * @vctxt: the WXS validation context
22576 *
22577 * Pops all XPath states.
22578 *
22579 * Returns 0 on success and -1 on internal errors.
22580 */
22581static int
22582xmlSchemaXPathPop(xmlSchemaValidCtxtPtr vctxt)
22583{
22584 xmlSchemaIDCStateObjPtr sto;
22585 int res;
22586
22587 if (vctxt->xpathStates == NULL((void*)0))
22588 return(0);
22589 sto = vctxt->xpathStates;
22590 do {
22591 res = xmlStreamPop((xmlStreamCtxtPtr) sto->xpathCtxt);
22592 if (res == -1)
22593 return (-1);
22594 sto = sto->next;
22595 } while (sto != NULL((void*)0));
22596 return(0);
22597}
22598
22599/**
22600 * xmlSchemaXPathProcessHistory:
22601 * @vctxt: the WXS validation context
22602 * @type: the simple/complex type of the current node if any at all
22603 * @val: the precompiled value
22604 *
22605 * Processes and pops the history items of the IDC state objects.
22606 * IDC key-sequences are validated/created on IDC bindings.
22607 *
22608 * Returns 0 on success and -1 on internal errors.
22609 */
22610static int
22611xmlSchemaXPathProcessHistory(xmlSchemaValidCtxtPtr vctxt,
22612 int depth)
22613{
22614 xmlSchemaIDCStateObjPtr sto, nextsto;
22615 int res, matchDepth;
22616 xmlSchemaPSVIIDCKeyPtr key = NULL((void*)0);
22617 xmlSchemaTypePtr type = vctxt->inode->typeDef, simpleType = NULL((void*)0);
22618
22619 if (vctxt->xpathStates == NULL((void*)0))
22620 return (0);
22621 sto = vctxt->xpathStates;
22622
22623 /*
22624 * Evaluate the state objects.
22625 */
22626 while (sto != NULL((void*)0)) {
22627 res = xmlStreamPop((xmlStreamCtxtPtr) sto->xpathCtxt);
22628 if (res == -1) {
22629 VERROR_INT("xmlSchemaXPathProcessHistory",xmlSchemaInternalErr((xmlSchemaAbstractCtxtPtr) vctxt, "xmlSchemaXPathProcessHistory"
, "calling xmlStreamPop()");
22630 "calling xmlStreamPop()")xmlSchemaInternalErr((xmlSchemaAbstractCtxtPtr) vctxt, "xmlSchemaXPathProcessHistory"
, "calling xmlStreamPop()");
;
22631 return (-1);
22632 }
22633 if (sto->nbHistory == 0)
22634 goto deregister_check;
22635
22636 matchDepth = sto->history[sto->nbHistory -1];
22637
22638 /*
22639 * Only matches at the current depth are of interest.
22640 */
22641 if (matchDepth != depth) {
22642 sto = sto->next;
22643 continue;
22644 }
22645 if (sto->type == XPATH_STATE_OBJ_TYPE_IDC_FIELD2) {
22646 /*
22647 * NOTE: According to
22648 * http://www.w3.org/Bugs/Public/show_bug.cgi?id=2198
22649 * ... the simple-content of complex types is also allowed.
22650 */
22651
22652 if (WXS_IS_COMPLEX(type)(((type)->type == XML_SCHEMA_TYPE_COMPLEX) || ((type)->
builtInType == XML_SCHEMAS_ANYTYPE))
) {
22653 if (WXS_HAS_SIMPLE_CONTENT(type)((type->contentType == XML_SCHEMA_CONTENT_SIMPLE) || (type
->contentType == XML_SCHEMA_CONTENT_BASIC))
) {
22654 /*
22655 * Sanity check for complex types with simple content.
22656 */
22657 simpleType = type->contentTypeDef;
22658 if (simpleType == NULL((void*)0)) {
22659 VERROR_INT("xmlSchemaXPathProcessHistory",xmlSchemaInternalErr((xmlSchemaAbstractCtxtPtr) vctxt, "xmlSchemaXPathProcessHistory"
, "field resolves to a CT with simple content " "but the CT is missing the ST definition"
);
22660 "field resolves to a CT with simple content "xmlSchemaInternalErr((xmlSchemaAbstractCtxtPtr) vctxt, "xmlSchemaXPathProcessHistory"
, "field resolves to a CT with simple content " "but the CT is missing the ST definition"
);
22661 "but the CT is missing the ST definition")xmlSchemaInternalErr((xmlSchemaAbstractCtxtPtr) vctxt, "xmlSchemaXPathProcessHistory"
, "field resolves to a CT with simple content " "but the CT is missing the ST definition"
);
;
22662 return (-1);
22663 }
22664 } else
22665 simpleType = NULL((void*)0);
22666 } else
22667 simpleType = type;
22668 if (simpleType == NULL((void*)0)) {
22669 xmlChar *str = NULL((void*)0);
22670
22671 /*
22672 * Not qualified if the field resolves to a node of non
22673 * simple type.
22674 */
22675 xmlSchemaCustomErr(ACTXT_CAST(xmlSchemaAbstractCtxtPtr) vctxt,
22676 XML_SCHEMAV_CVC_IDC, NULL((void*)0),
22677 WXS_BASIC_CAST(xmlSchemaBasicItemPtr) sto->matcher->aidc->def,
22678 "The XPath '%s' of a field of %s does evaluate to a node of "
22679 "non-simple type",
22680 sto->sel->xpath,
22681 xmlSchemaGetIDCDesignation(&str, sto->matcher->aidc->def));
22682 FREE_AND_NULL(str)if ((str) != ((void*)0)) { xmlFree((xmlChar *) (str)); str = (
(void*)0); }
;
22683 sto->nbHistory--;
22684 goto deregister_check;
22685 }
22686
22687 if ((key == NULL((void*)0)) && (vctxt->inode->val == NULL((void*)0))) {
22688 /*
22689 * Failed to provide the normalized value; maybe
22690 * the value was invalid.
22691 */
22692 VERROR(XML_SCHEMAV_CVC_IDC,xmlSchemaCustomErr((xmlSchemaAbstractCtxtPtr) vctxt, XML_SCHEMAV_CVC_IDC
, ((void*)0), (xmlSchemaBasicItemPtr) sto->matcher->aidc
->def, "Warning: No precomputed value available, the value "
"was either invalid or something strange happened", ((void*)
0), ((void*)0));
22693 WXS_BASIC_CAST sto->matcher->aidc->def,xmlSchemaCustomErr((xmlSchemaAbstractCtxtPtr) vctxt, XML_SCHEMAV_CVC_IDC
, ((void*)0), (xmlSchemaBasicItemPtr) sto->matcher->aidc
->def, "Warning: No precomputed value available, the value "
"was either invalid or something strange happened", ((void*)
0), ((void*)0));
22694 "Warning: No precomputed value available, the value "xmlSchemaCustomErr((xmlSchemaAbstractCtxtPtr) vctxt, XML_SCHEMAV_CVC_IDC
, ((void*)0), (xmlSchemaBasicItemPtr) sto->matcher->aidc
->def, "Warning: No precomputed value available, the value "
"was either invalid or something strange happened", ((void*)
0), ((void*)0));
22695 "was either invalid or something strange happened")xmlSchemaCustomErr((xmlSchemaAbstractCtxtPtr) vctxt, XML_SCHEMAV_CVC_IDC
, ((void*)0), (xmlSchemaBasicItemPtr) sto->matcher->aidc
->def, "Warning: No precomputed value available, the value "
"was either invalid or something strange happened", ((void*)
0), ((void*)0));
;
22696 sto->nbHistory--;
22697 goto deregister_check;
22698 } else {
22699 xmlSchemaIDCMatcherPtr matcher = sto->matcher;
22700 xmlSchemaPSVIIDCKeyPtr *keySeq;
22701 int pos, idx;
22702
22703 /*
22704 * The key will be anchored on the matcher's list of
22705 * key-sequences. The position in this list is determined
22706 * by the target node's depth relative to the matcher's
22707 * depth of creation (i.e. the depth of the scope element).
22708 *
22709 * Element Depth Pos List-entries
22710 * <scope> 0 NULL
22711 * <bar> 1 NULL
22712 * <target/> 2 2 target
22713 * <bar>
22714 * </scope>
22715 *
22716 * The size of the list is only dependent on the depth of
22717 * the tree.
22718 * An entry will be NULLed in selector_leave, i.e. when
22719 * we hit the target's
22720 */
22721 pos = sto->depth - matcher->depth;
22722 idx = sto->sel->index;
22723
22724 /*
22725 * Create/grow the array of key-sequences.
22726 */
22727 if (matcher->keySeqs == NULL((void*)0)) {
22728 if (pos > 9)
22729 matcher->sizeKeySeqs = pos * 2;
22730 else
22731 matcher->sizeKeySeqs = 10;
22732 matcher->keySeqs = (xmlSchemaPSVIIDCKeyPtr **)
22733 xmlMalloc(matcher->sizeKeySeqs *
22734 sizeof(xmlSchemaPSVIIDCKeyPtr *));
22735 if (matcher->keySeqs == NULL((void*)0)) {
22736 xmlSchemaVErrMemory(NULL((void*)0),
22737 "allocating an array of key-sequences",
22738 NULL((void*)0));
22739 return(-1);
22740 }
22741 memset(matcher->keySeqs, 0,
22742 matcher->sizeKeySeqs *
22743 sizeof(xmlSchemaPSVIIDCKeyPtr *));
22744 } else if (pos >= matcher->sizeKeySeqs) {
22745 int i = matcher->sizeKeySeqs;
22746
22747 matcher->sizeKeySeqs = pos * 2;
22748 matcher->keySeqs = (xmlSchemaPSVIIDCKeyPtr **)
22749 xmlRealloc(matcher->keySeqs,
22750 matcher->sizeKeySeqs *
22751 sizeof(xmlSchemaPSVIIDCKeyPtr *));
22752 if (matcher->keySeqs == NULL((void*)0)) {
22753 xmlSchemaVErrMemory(NULL((void*)0),
22754 "reallocating an array of key-sequences",
22755 NULL((void*)0));
22756 return (-1);
22757 }
22758 /*
22759 * The array needs to be NULLed.
22760 * TODO: Use memset?
22761 */
22762 for (; i < matcher->sizeKeySeqs; i++)
22763 matcher->keySeqs[i] = NULL((void*)0);
22764 }
22765
22766 /*
22767 * Get/create the key-sequence.
22768 */
22769 keySeq = matcher->keySeqs[pos];
22770 if (keySeq == NULL((void*)0)) {
22771 goto create_sequence;
22772 } else if (keySeq[idx] != NULL((void*)0)) {
22773 xmlChar *str = NULL((void*)0);
22774 /*
22775 * cvc-identity-constraint:
22776 * 3 For each node in the `target node set` all
22777 * of the {fields}, with that node as the context
22778 * node, evaluate to either an empty node-set or
22779 * a node-set with exactly one member, which must
22780 * have a simple type.
22781 *
22782 * The key was already set; report an error.
22783 */
22784 xmlSchemaCustomErr(ACTXT_CAST(xmlSchemaAbstractCtxtPtr) vctxt,
22785 XML_SCHEMAV_CVC_IDC, NULL((void*)0),
22786 WXS_BASIC_CAST(xmlSchemaBasicItemPtr) matcher->aidc->def,
22787 "The XPath '%s' of a field of %s evaluates to a "
22788 "node-set with more than one member",
22789 sto->sel->xpath,
22790 xmlSchemaGetIDCDesignation(&str, matcher->aidc->def));
22791 FREE_AND_NULL(str)if ((str) != ((void*)0)) { xmlFree((xmlChar *) (str)); str = (
(void*)0); }
;
22792 sto->nbHistory--;
22793 goto deregister_check;
22794 } else
22795 goto create_key;
22796
22797create_sequence:
22798 /*
22799 * Create a key-sequence.
22800 */
22801 keySeq = (xmlSchemaPSVIIDCKeyPtr *) xmlMalloc(
22802 matcher->aidc->def->nbFields *
22803 sizeof(xmlSchemaPSVIIDCKeyPtr));
22804 if (keySeq == NULL((void*)0)) {
22805 xmlSchemaVErrMemory(NULL((void*)0),
22806 "allocating an IDC key-sequence", NULL((void*)0));
22807 return(-1);
22808 }
22809 memset(keySeq, 0, matcher->aidc->def->nbFields *
22810 sizeof(xmlSchemaPSVIIDCKeyPtr));
22811 matcher->keySeqs[pos] = keySeq;
22812create_key:
22813 /*
22814 * Create a key once per node only.
22815 */
22816 if (key == NULL((void*)0)) {
22817 key = (xmlSchemaPSVIIDCKeyPtr) xmlMalloc(
22818 sizeof(xmlSchemaPSVIIDCKey));
22819 if (key == NULL((void*)0)) {
22820 xmlSchemaVErrMemory(NULL((void*)0),
22821 "allocating a IDC key", NULL((void*)0));
22822 xmlFree(keySeq);
22823 matcher->keySeqs[pos] = NULL((void*)0);
22824 return(-1);
22825 }
22826 /*
22827 * Consume the compiled value.
22828 */
22829 key->type = simpleType;
22830 key->val = vctxt->inode->val;
22831 vctxt->inode->val = NULL((void*)0);
22832 /*
22833 * Store the key in a global list.
22834 */
22835 if (xmlSchemaIDCStoreKey(vctxt, key) == -1) {
22836 xmlSchemaIDCFreeKey(key);
22837 return (-1);
22838 }
22839 }
22840 keySeq[idx] = key;
22841 }
22842 } else if (sto->type == XPATH_STATE_OBJ_TYPE_IDC_SELECTOR1) {
22843
22844 xmlSchemaPSVIIDCKeyPtr **keySeq = NULL((void*)0);
22845 /* xmlSchemaPSVIIDCBindingPtr bind; */
22846 xmlSchemaPSVIIDCNodePtr ntItem;
22847 xmlSchemaIDCMatcherPtr matcher;
22848 xmlSchemaIDCPtr idc;
22849 xmlSchemaItemListPtr targets;
22850 int pos, i, j, nbKeys;
22851 /*
22852 * Here we have the following scenario:
22853 * An IDC 'selector' state object resolved to a target node,
22854 * during the time this target node was in the
22855 * ancestor-or-self axis, the 'field' state object(s) looked
22856 * out for matching nodes to create a key-sequence for this
22857 * target node. Now we are back to this target node and need
22858 * to put the key-sequence, together with the target node
22859 * itself, into the node-table of the corresponding IDC
22860 * binding.
22861 */
22862 matcher = sto->matcher;
22863 idc = matcher->aidc->def;
22864 nbKeys = idc->nbFields;
22865 pos = depth - matcher->depth;
22866 /*
22867 * Check if the matcher has any key-sequences at all, plus
22868 * if it has a key-sequence for the current target node.
22869 */
22870 if ((matcher->keySeqs == NULL((void*)0)) ||
22871 (matcher->sizeKeySeqs <= pos)) {
22872 if (idc->type == XML_SCHEMA_TYPE_IDC_KEY)
22873 goto selector_key_error;
22874 else
22875 goto selector_leave;
22876 }
22877
22878 keySeq = &(matcher->keySeqs[pos]);
22879 if (*keySeq == NULL((void*)0)) {
22880 if (idc->type == XML_SCHEMA_TYPE_IDC_KEY)
22881 goto selector_key_error;
22882 else
22883 goto selector_leave;
22884 }
22885
22886 for (i = 0; i < nbKeys; i++) {
22887 if ((*keySeq)[i] == NULL((void*)0)) {
22888 /*
22889 * Not qualified, if not all fields did resolve.
22890 */
22891 if (idc->type == XML_SCHEMA_TYPE_IDC_KEY) {
22892 /*
22893 * All fields of a "key" IDC must resolve.
22894 */
22895 goto selector_key_error;
22896 }
22897 goto selector_leave;
22898 }
22899 }
22900 /*
22901 * All fields did resolve.
22902 */
22903
22904 /*
22905 * 4.1 If the {identity-constraint category} is unique(/key),
22906 * then no two members of the `qualified node set` have
22907 * `key-sequences` whose members are pairwise equal, as
22908 * defined by Equal in [XML Schemas: Datatypes].
22909 *
22910 * Get the IDC binding from the matcher and check for
22911 * duplicate key-sequences.
22912 */
22913#if 0
22914 bind = xmlSchemaIDCAcquireBinding(vctxt, matcher);
22915#endif
22916 targets = xmlSchemaIDCAcquireTargetList(vctxt, matcher);
22917 if ((idc->type != XML_SCHEMA_TYPE_IDC_KEYREF) &&
22918 (targets->nbItems != 0)) {
22919 xmlSchemaPSVIIDCKeyPtr ckey, bkey, *bkeySeq;
22920 xmlIDCHashEntryPtr e;
22921
22922 res = 0;
22923
22924 if (!matcher->htab)
22925 e = NULL((void*)0);
22926 else {
22927 xmlChar *value = NULL((void*)0);
22928 xmlSchemaHashKeySequence(vctxt, &value, *keySeq, nbKeys);
22929 e = xmlHashLookup(matcher->htab, value);
22930 FREE_AND_NULL(value)if ((value) != ((void*)0)) { xmlFree((xmlChar *) (value)); value
= ((void*)0); }
;
22931 }
22932
22933 /*
22934 * Compare the key-sequences, key by key.
22935 */
22936 for (;e; e = e->next) {
22937 bkeySeq =
22938 ((xmlSchemaPSVIIDCNodePtr) targets->items[e->index])->keys;
22939 for (j = 0; j < nbKeys; j++) {
22940 ckey = (*keySeq)[j];
22941 bkey = bkeySeq[j];
22942 res = xmlSchemaAreValuesEqual(ckey->val, bkey->val);
22943 if (res == -1) {
22944 return (-1);
22945 } else if (res == 0) {
22946 /*
22947 * One of the keys differs, so the key-sequence
22948 * won't be equal; get out.
22949 */
22950 break;
22951 }
22952 }
22953 if (res == 1) {
22954 /*
22955 * Duplicate key-sequence found.
22956 */
22957 break;
22958 }
22959 }
22960 if (e) {
22961 xmlChar *str = NULL((void*)0), *strB = NULL((void*)0);
22962 /*
22963 * TODO: Try to report the key-sequence.
22964 */
22965 xmlSchemaCustomErr(ACTXT_CAST(xmlSchemaAbstractCtxtPtr) vctxt,
22966 XML_SCHEMAV_CVC_IDC, NULL((void*)0),
22967 WXS_BASIC_CAST(xmlSchemaBasicItemPtr) idc,
22968 "Duplicate key-sequence %s in %s",
22969 xmlSchemaFormatIDCKeySequence(vctxt, &str,
22970 (*keySeq), nbKeys),
22971 xmlSchemaGetIDCDesignation(&strB, idc));
22972 FREE_AND_NULL(str)if ((str) != ((void*)0)) { xmlFree((xmlChar *) (str)); str = (
(void*)0); }
;
22973 FREE_AND_NULL(strB)if ((strB) != ((void*)0)) { xmlFree((xmlChar *) (strB)); strB
= ((void*)0); }
;
22974 goto selector_leave;
22975 }
22976 }
22977 /*
22978 * Add a node-table item to the IDC binding.
22979 */
22980 ntItem = (xmlSchemaPSVIIDCNodePtr) xmlMalloc(
22981 sizeof(xmlSchemaPSVIIDCNode));
22982 if (ntItem == NULL((void*)0)) {
22983 xmlSchemaVErrMemory(NULL((void*)0),
22984 "allocating an IDC node-table item", NULL((void*)0));
22985 xmlFree(*keySeq);
22986 *keySeq = NULL((void*)0);
22987 return(-1);
22988 }
22989 memset(ntItem, 0, sizeof(xmlSchemaPSVIIDCNode));
22990
22991 /*
22992 * Store the node-table item in a global list.
22993 */
22994 if (idc->type != XML_SCHEMA_TYPE_IDC_KEYREF) {
22995 if (xmlSchemaIDCStoreNodeTableItem(vctxt, ntItem) == -1) {
22996 xmlFree(ntItem);
22997 xmlFree(*keySeq);
22998 *keySeq = NULL((void*)0);
22999 return (-1);
23000 }
23001 ntItem->nodeQNameID = -1;
23002 } else {
23003 /*
23004 * Save a cached QName for this node on the IDC node, to be
23005 * able to report it, even if the node is not saved.
23006 */
23007 ntItem->nodeQNameID = xmlSchemaVAddNodeQName(vctxt,
23008 vctxt->inode->localName, vctxt->inode->nsName);
23009 if (ntItem->nodeQNameID == -1) {
23010 xmlFree(ntItem);
23011 xmlFree(*keySeq);
23012 *keySeq = NULL((void*)0);
23013 return (-1);
23014 }
23015 }
23016 /*
23017 * Init the node-table item: Save the node, position and
23018 * consume the key-sequence.
23019 */
23020 ntItem->node = vctxt->node;
23021 ntItem->nodeLine = vctxt->inode->nodeLine;
23022 ntItem->keys = *keySeq;
23023 *keySeq = NULL((void*)0);
23024#if 0
23025 if (xmlSchemaIDCAppendNodeTableItem(bind, ntItem) == -1)
23026#endif
23027 if (xmlSchemaItemListAdd(targets, ntItem) == -1) {
23028 if (idc->type == XML_SCHEMA_TYPE_IDC_KEYREF) {
23029 /*
23030 * Free the item, since keyref items won't be
23031 * put on a global list.
23032 */
23033 xmlFree(ntItem->keys);
23034 xmlFree(ntItem);
23035 }
23036 return (-1);
23037 }
23038 if (idc->type != XML_SCHEMA_TYPE_IDC_KEYREF) {
23039 xmlChar *value = NULL((void*)0);
23040 xmlIDCHashEntryPtr r, e;
23041 if (!matcher->htab)
23042 matcher->htab = xmlHashCreate(4);
23043 xmlSchemaHashKeySequence(vctxt, &value, ntItem->keys, nbKeys);
23044 e = xmlMalloc(sizeof *e);
23045 e->index = targets->nbItems - 1;
23046 r = xmlHashLookup(matcher->htab, value);
23047 if (r) {
23048 e->next = r->next;
23049 r->next = e;
23050 } else {
23051 e->next = NULL((void*)0);
23052 xmlHashAddEntry(matcher->htab, value, e);
23053 }
23054 FREE_AND_NULL(value)if ((value) != ((void*)0)) { xmlFree((xmlChar *) (value)); value
= ((void*)0); }
;
23055 }
23056
23057 goto selector_leave;
23058selector_key_error:
23059 {
23060 xmlChar *str = NULL((void*)0);
23061 /*
23062 * 4.2.1 (KEY) The `target node set` and the
23063 * `qualified node set` are equal, that is, every
23064 * member of the `target node set` is also a member
23065 * of the `qualified node set` and vice versa.
23066 */
23067 xmlSchemaCustomErr(ACTXT_CAST(xmlSchemaAbstractCtxtPtr) vctxt,
23068 XML_SCHEMAV_CVC_IDC, NULL((void*)0),
23069 WXS_BASIC_CAST(xmlSchemaBasicItemPtr) idc,
23070 "Not all fields of %s evaluate to a node",
23071 xmlSchemaGetIDCDesignation(&str, idc), NULL((void*)0));
23072 FREE_AND_NULL(str)if ((str) != ((void*)0)) { xmlFree((xmlChar *) (str)); str = (
(void*)0); }
;
23073 }
23074selector_leave:
23075 /*
23076 * Free the key-sequence if not added to the IDC table.
23077 */
23078 if ((keySeq != NULL((void*)0)) && (*keySeq != NULL((void*)0))) {
23079 xmlFree(*keySeq);
23080 *keySeq = NULL((void*)0);
23081 }
23082 } /* if selector */
23083
23084 sto->nbHistory--;
23085
23086deregister_check:
23087 /*
23088 * Deregister state objects if they reach the depth of creation.
23089 */
23090 if ((sto->nbHistory == 0) && (sto->depth == depth)) {
23091 if (vctxt->xpathStates != sto) {
23092 VERROR_INT("xmlSchemaXPathProcessHistory",xmlSchemaInternalErr((xmlSchemaAbstractCtxtPtr) vctxt, "xmlSchemaXPathProcessHistory"
, "The state object to be removed is not the first " "in the list"
);
23093 "The state object to be removed is not the first "xmlSchemaInternalErr((xmlSchemaAbstractCtxtPtr) vctxt, "xmlSchemaXPathProcessHistory"
, "The state object to be removed is not the first " "in the list"
);
23094 "in the list")xmlSchemaInternalErr((xmlSchemaAbstractCtxtPtr) vctxt, "xmlSchemaXPathProcessHistory"
, "The state object to be removed is not the first " "in the list"
);
;
23095 }
23096 nextsto = sto->next;
23097 /*
23098 * Unlink from the list of active XPath state objects.
23099 */
23100 vctxt->xpathStates = sto->next;
23101 sto->next = vctxt->xpathStatePool;
23102 /*
23103 * Link it to the pool of reusable state objects.
23104 */
23105 vctxt->xpathStatePool = sto;
23106 sto = nextsto;
23107 } else
23108 sto = sto->next;
23109 } /* while (sto != NULL) */
23110 return (0);
23111}
23112
23113/**
23114 * xmlSchemaIDCRegisterMatchers:
23115 * @vctxt: the WXS validation context
23116 * @elemDecl: the element declaration
23117 *
23118 * Creates helper objects to evaluate IDC selectors/fields
23119 * successively.
23120 *
23121 * Returns 0 if OK and -1 on internal errors.
23122 */
23123static int
23124xmlSchemaIDCRegisterMatchers(xmlSchemaValidCtxtPtr vctxt,
23125 xmlSchemaElementPtr elemDecl)
23126{
23127 xmlSchemaIDCMatcherPtr matcher, last = NULL((void*)0);
23128 xmlSchemaIDCPtr idc, refIdc;
23129 xmlSchemaIDCAugPtr aidc;
23130
23131 idc = (xmlSchemaIDCPtr) elemDecl->idcs;
23132 if (idc == NULL((void*)0))
23133 return (0);
23134
23135 if (vctxt->inode->idcMatchers != NULL((void*)0)) {
23136 VERROR_INT("xmlSchemaIDCRegisterMatchers",xmlSchemaInternalErr((xmlSchemaAbstractCtxtPtr) vctxt, "xmlSchemaIDCRegisterMatchers"
, "The chain of IDC matchers is expected to be empty");
23137 "The chain of IDC matchers is expected to be empty")xmlSchemaInternalErr((xmlSchemaAbstractCtxtPtr) vctxt, "xmlSchemaIDCRegisterMatchers"
, "The chain of IDC matchers is expected to be empty");
;
23138 return (-1);
23139 }
23140 do {
23141 if (idc->type == XML_SCHEMA_TYPE_IDC_KEYREF) {
23142 /*
23143 * Since IDCs bubbles are expensive we need to know the
23144 * depth at which the bubbles should stop; this will be
23145 * the depth of the top-most keyref IDC. If no keyref
23146 * references a key/unique IDC, the keyrefDepth will
23147 * be -1, indicating that no bubbles are needed.
23148 */
23149 refIdc = (xmlSchemaIDCPtr) idc->ref->item;
23150 if (refIdc != NULL((void*)0)) {
23151 /*
23152 * Remember that we have keyrefs on this node.
23153 */
23154 vctxt->inode->hasKeyrefs = 1;
23155 /*
23156 * Lookup the referenced augmented IDC info.
23157 */
23158 aidc = vctxt->aidcs;
23159 while (aidc != NULL((void*)0)) {
23160 if (aidc->def == refIdc)
23161 break;
23162 aidc = aidc->next;
23163 }
23164 if (aidc == NULL((void*)0)) {
23165 VERROR_INT("xmlSchemaIDCRegisterMatchers",xmlSchemaInternalErr((xmlSchemaAbstractCtxtPtr) vctxt, "xmlSchemaIDCRegisterMatchers"
, "Could not find an augmented IDC item for an IDC " "definition"
);
23166 "Could not find an augmented IDC item for an IDC "xmlSchemaInternalErr((xmlSchemaAbstractCtxtPtr) vctxt, "xmlSchemaIDCRegisterMatchers"
, "Could not find an augmented IDC item for an IDC " "definition"
);
23167 "definition")xmlSchemaInternalErr((xmlSchemaAbstractCtxtPtr) vctxt, "xmlSchemaIDCRegisterMatchers"
, "Could not find an augmented IDC item for an IDC " "definition"
);
;
23168 return (-1);
23169 }
23170 if ((aidc->keyrefDepth == -1) ||
23171 (vctxt->depth < aidc->keyrefDepth))
23172 aidc->keyrefDepth = vctxt->depth;
23173 }
23174 }
23175 /*
23176 * Lookup the augmented IDC item for the IDC definition.
23177 */
23178 aidc = vctxt->aidcs;
23179 while (aidc != NULL((void*)0)) {
23180 if (aidc->def == idc)
23181 break;
23182 aidc = aidc->next;
23183 }
23184 if (aidc == NULL((void*)0)) {
23185 VERROR_INT("xmlSchemaIDCRegisterMatchers",xmlSchemaInternalErr((xmlSchemaAbstractCtxtPtr) vctxt, "xmlSchemaIDCRegisterMatchers"
, "Could not find an augmented IDC item for an IDC definition"
);
23186 "Could not find an augmented IDC item for an IDC definition")xmlSchemaInternalErr((xmlSchemaAbstractCtxtPtr) vctxt, "xmlSchemaIDCRegisterMatchers"
, "Could not find an augmented IDC item for an IDC definition"
);
;
23187 return (-1);
23188 }
23189 /*
23190 * Create an IDC matcher for every IDC definition.
23191 */
23192 if (vctxt->idcMatcherCache != NULL((void*)0)) {
23193 /*
23194 * Reuse a cached matcher.
23195 */
23196 matcher = vctxt->idcMatcherCache;
23197 vctxt->idcMatcherCache = matcher->nextCached;
23198 matcher->nextCached = NULL((void*)0);
23199 } else {
23200 matcher = (xmlSchemaIDCMatcherPtr)
23201 xmlMalloc(sizeof(xmlSchemaIDCMatcher));
23202 if (matcher == NULL((void*)0)) {
23203 xmlSchemaVErrMemory(vctxt,
23204 "allocating an IDC matcher", NULL((void*)0));
23205 return (-1);
23206 }
23207 memset(matcher, 0, sizeof(xmlSchemaIDCMatcher));
23208 }
23209 if (last == NULL((void*)0))
23210 vctxt->inode->idcMatchers = matcher;
23211 else
23212 last->next = matcher;
23213 last = matcher;
23214
23215 matcher->type = IDC_MATCHER0;
23216 matcher->depth = vctxt->depth;
23217 matcher->aidc = aidc;
23218 matcher->idcType = aidc->def->type;
23219 /*
23220 * Init the automaton state object.
23221 */
23222 if (xmlSchemaIDCAddStateObject(vctxt, matcher,
23223 idc->selector, XPATH_STATE_OBJ_TYPE_IDC_SELECTOR1) == -1)
23224 return (-1);
23225
23226 idc = idc->next;
23227 } while (idc != NULL((void*)0));
23228 return (0);
23229}
23230
23231static int
23232xmlSchemaIDCFillNodeTables(xmlSchemaValidCtxtPtr vctxt,
23233 xmlSchemaNodeInfoPtr ielem)
23234{
23235 xmlSchemaPSVIIDCBindingPtr bind;
23236 int res, i, j, k, nbTargets, nbFields, nbDupls, nbNodeTable;
23237 xmlSchemaPSVIIDCKeyPtr *keys, *ntkeys;
23238 xmlSchemaPSVIIDCNodePtr *targets, *dupls;
23239
23240 xmlSchemaIDCMatcherPtr matcher = ielem->idcMatchers;
23241 /* vctxt->createIDCNodeTables */
23242 while (matcher != NULL((void*)0)) {
23243 /*
23244 * Skip keyref IDCs and empty IDC target-lists.
23245 */
23246 if ((matcher->aidc->def->type == XML_SCHEMA_TYPE_IDC_KEYREF) ||
23247 WXS_ILIST_IS_EMPTY(matcher->targets)((matcher->targets == ((void*)0)) || ((matcher->targets
)->nbItems == 0))
)
23248 {
23249 matcher = matcher->next;
23250 continue;
23251 }
23252 /*
23253 * If we _want_ the IDC node-table to be created in any case
23254 * then do so. Otherwise create them only if keyrefs need them.
23255 */
23256 if ((! vctxt->createIDCNodeTables) &&
23257 ((matcher->aidc->keyrefDepth == -1) ||
23258 (matcher->aidc->keyrefDepth > vctxt->depth)))
23259 {
23260 matcher = matcher->next;
23261 continue;
23262 }
23263 /*
23264 * Get/create the IDC binding on this element for the IDC definition.
23265 */
23266 bind = xmlSchemaIDCAcquireBinding(vctxt, matcher);
23267 if (bind == NULL((void*)0))
23268 goto internal_error;
23269
23270 if (! WXS_ILIST_IS_EMPTY(bind->dupls)((bind->dupls == ((void*)0)) || ((bind->dupls)->nbItems
== 0))
) {
23271 dupls = (xmlSchemaPSVIIDCNodePtr *) bind->dupls->items;
23272 nbDupls = bind->dupls->nbItems;
23273 } else {
23274 dupls = NULL((void*)0);
23275 nbDupls = 0;
23276 }
23277 if (bind->nodeTable != NULL((void*)0)) {
23278 nbNodeTable = bind->nbNodes;
23279 } else {
23280 nbNodeTable = 0;
23281 }
23282
23283 if ((nbNodeTable == 0) && (nbDupls == 0)) {
23284 /*
23285 * Transfer all IDC target-nodes to the IDC node-table.
23286 */
23287 bind->nodeTable =
23288 (xmlSchemaPSVIIDCNodePtr *) matcher->targets->items;
23289 bind->sizeNodes = matcher->targets->sizeItems;
23290 bind->nbNodes = matcher->targets->nbItems;
23291
23292 matcher->targets->items = NULL((void*)0);
23293 matcher->targets->sizeItems = 0;
23294 matcher->targets->nbItems = 0;
23295 if (matcher->htab) {
23296 xmlHashFree(matcher->htab, xmlFreeIDCHashEntry);
23297 matcher->htab = NULL((void*)0);
23298 }
23299 } else {
23300 /*
23301 * Compare the key-sequences and add to the IDC node-table.
23302 */
23303 nbTargets = matcher->targets->nbItems;
23304 targets = (xmlSchemaPSVIIDCNodePtr *) matcher->targets->items;
23305 nbFields = matcher->aidc->def->nbFields;
23306 i = 0;
23307 do {
23308 keys = targets[i]->keys;
23309 if (nbDupls) {
23310 /*
23311 * Search in already found duplicates first.
23312 */
23313 j = 0;
23314 do {
23315 if (nbFields == 1) {
23316 res = xmlSchemaAreValuesEqual(keys[0]->val,
23317 dupls[j]->keys[0]->val);
23318 if (res == -1)
23319 goto internal_error;
23320 if (res == 1) {
23321 /*
23322 * Equal key-sequence.
23323 */
23324 goto next_target;
23325 }
23326 } else {
23327 res = 0;
23328 ntkeys = dupls[j]->keys;
23329 for (k = 0; k < nbFields; k++) {
23330 res = xmlSchemaAreValuesEqual(keys[k]->val,
23331 ntkeys[k]->val);
23332 if (res == -1)
23333 goto internal_error;
23334 if (res == 0) {
23335 /*
23336 * One of the keys differs.
23337 */
23338 break;
23339 }
23340 }
23341 if (res == 1) {
23342 /*
23343 * Equal key-sequence found.
23344 */
23345 goto next_target;
23346 }
23347 }
23348 j++;
23349 } while (j < nbDupls);
23350 }
23351 if (nbNodeTable) {
23352 j = 0;
23353 do {
23354 if (nbFields == 1) {
23355 res = xmlSchemaAreValuesEqual(keys[0]->val,
23356 bind->nodeTable[j]->keys[0]->val);
23357 if (res == -1)
23358 goto internal_error;
23359 if (res == 0) {
23360 /*
23361 * The key-sequence differs.
23362 */
23363 goto next_node_table_entry;
23364 }
23365 } else {
23366 res = 0;
Value stored to 'res' is never read
23367 ntkeys = bind->nodeTable[j]->keys;
23368 for (k = 0; k < nbFields; k++) {
23369 res = xmlSchemaAreValuesEqual(keys[k]->val,
23370 ntkeys[k]->val);
23371 if (res == -1)
23372 goto internal_error;
23373 if (res == 0) {
23374 /*
23375 * One of the keys differs.
23376 */
23377 goto next_node_table_entry;
23378 }
23379 }
23380 }
23381 /*
23382 * Add the duplicate to the list of duplicates.
23383 */
23384 if (bind->dupls == NULL((void*)0)) {
23385 bind->dupls = xmlSchemaItemListCreate();
23386 if (bind->dupls == NULL((void*)0))
23387 goto internal_error;
23388 }
23389 if (xmlSchemaItemListAdd(bind->dupls, bind->nodeTable[j]) == -1)
23390 goto internal_error;
23391 dupls = (xmlSchemaPSVIIDCNodePtr *) bind->dupls->items;
23392 /*
23393 * Remove the duplicate entry from the IDC node-table.
23394 */
23395 bind->nodeTable[j] = bind->nodeTable[bind->nbNodes -1];
23396 bind->nbNodes--;
23397
23398 goto next_target;
23399
23400next_node_table_entry:
23401 j++;
23402 } while (j < nbNodeTable);
23403 }
23404 /*
23405 * If everything is fine, then add the IDC target-node to
23406 * the IDC node-table.
23407 */
23408 if (xmlSchemaIDCAppendNodeTableItem(bind, targets[i]) == -1)
23409 goto internal_error;
23410
23411next_target:
23412 i++;
23413 } while (i < nbTargets);
23414 }
23415 matcher = matcher->next;
23416 }
23417 return(0);
23418
23419internal_error:
23420 return(-1);
23421}
23422
23423/**
23424 * xmlSchemaBubbleIDCNodeTables:
23425 * @depth: the current tree depth
23426 *
23427 * Merges IDC bindings of an element at @depth into the corresponding IDC
23428 * bindings of its parent element. If a duplicate note-table entry is found,
23429 * both, the parent node-table entry and child entry are discarded from the
23430 * node-table of the parent.
23431 *
23432 * Returns 0 if OK and -1 on internal errors.
23433 */
23434static int
23435xmlSchemaBubbleIDCNodeTables(xmlSchemaValidCtxtPtr vctxt)
23436{
23437 xmlSchemaPSVIIDCBindingPtr bind; /* IDC bindings of the current node. */
23438 xmlSchemaPSVIIDCBindingPtr *parTable, parBind = NULL((void*)0); /* parent IDC bindings. */
23439 xmlSchemaPSVIIDCNodePtr node, parNode = NULL((void*)0), *dupls, *parNodes; /* node-table entries. */
23440 xmlSchemaIDCAugPtr aidc;
23441 int i, j, k, ret = 0, nbFields, oldNum, oldDupls;
23442
23443 bind = vctxt->inode->idcTable;
23444 if (bind == NULL((void*)0)) {
23445 /* Fine, no table, no bubbles. */
23446 return (0);
23447 }
23448
23449 parTable = &(vctxt->elemInfos[vctxt->depth -1]->idcTable);
23450 /*
23451 * Walk all bindings; create new or add to existing bindings.
23452 * Remove duplicate key-sequences.
23453 */
23454 while (bind != NULL((void*)0)) {
23455
23456 if ((bind->nbNodes == 0) && WXS_ILIST_IS_EMPTY(bind->dupls)((bind->dupls == ((void*)0)) || ((bind->dupls)->nbItems
== 0))
)
23457 goto next_binding;
23458 /*
23459 * Check if the key/unique IDC table needs to be bubbled.
23460 */
23461 if (! vctxt->createIDCNodeTables) {
23462 aidc = vctxt->aidcs;
23463 do {
23464 if (aidc->def == bind->definition) {
23465 if ((aidc->keyrefDepth == -1) ||
23466 (aidc->keyrefDepth >= vctxt->depth)) {
23467 goto next_binding;
23468 }
23469 break;
23470 }
23471 aidc = aidc->next;
23472 } while (aidc != NULL((void*)0));
23473 }
23474
23475 if (parTable != NULL((void*)0))
23476 parBind = *parTable;
23477 /*
23478 * Search a matching parent binding for the
23479 * IDC definition.
23480 */
23481 while (parBind != NULL((void*)0)) {
23482 if (parBind->definition == bind->definition)
23483 break;
23484 parBind = parBind->next;
23485 }
23486
23487 if (parBind != NULL((void*)0)) {
23488 /*
23489 * Compare every node-table entry of the child node,
23490 * i.e. the key-sequence within, ...
23491 */
23492 oldNum = parBind->nbNodes; /* Skip newly added items. */
23493
23494 if (! WXS_ILIST_IS_EMPTY(parBind->dupls)((parBind->dupls == ((void*)0)) || ((parBind->dupls)->
nbItems == 0))
) {
23495 oldDupls = parBind->dupls->nbItems;
23496 dupls = (xmlSchemaPSVIIDCNodePtr *) parBind->dupls->items;
23497 } else {
23498 dupls = NULL((void*)0);
23499 oldDupls = 0;
23500 }
23501
23502 parNodes = parBind->nodeTable;
23503 nbFields = bind->definition->nbFields;
23504
23505 for (i = 0; i < bind->nbNodes; i++) {
23506 node = bind->nodeTable[i];
23507 if (node == NULL((void*)0))
23508 continue;
23509 /*
23510 * ...with every key-sequence of the parent node, already
23511 * evaluated to be a duplicate key-sequence.
23512 */
23513 if (oldDupls) {
23514 j = 0;
23515 while (j < oldDupls) {
23516 if (nbFields == 1) {
23517 ret = xmlSchemaAreValuesEqual(
23518 node->keys[0]->val,
23519 dupls[j]->keys[0]->val);
23520 if (ret == -1)
23521 goto internal_error;
23522 if (ret == 0) {
23523 j++;
23524 continue;
23525 }
23526 } else {
23527 parNode = dupls[j];
23528 for (k = 0; k < nbFields; k++) {
23529 ret = xmlSchemaAreValuesEqual(
23530 node->keys[k]->val,
23531 parNode->keys[k]->val);
23532 if (ret == -1)
23533 goto internal_error;
23534 if (ret == 0)
23535 break;
23536 }
23537 }
23538 if (ret == 1)
23539 /* Duplicate found. */
23540 break;
23541 j++;
23542 }
23543 if (j != oldDupls) {
23544 /* Duplicate found. Skip this entry. */
23545 continue;
23546 }
23547 }
23548 /*
23549 * ... and with every key-sequence of the parent node.
23550 */
23551 if (oldNum) {
23552 j = 0;
23553 while (j < oldNum) {
23554 parNode = parNodes[j];
23555 if (nbFields == 1) {
23556 ret = xmlSchemaAreValuesEqual(
23557 node->keys[0]->val,
23558 parNode->keys[0]->val);
23559 if (ret == -1)
23560 goto internal_error;
23561 if (ret == 0) {
23562 j++;
23563 continue;
23564 }
23565 } else {
23566 for (k = 0; k < nbFields; k++) {
23567 ret = xmlSchemaAreValuesEqual(
23568 node->keys[k]->val,
23569 parNode->keys[k]->val);
23570 if (ret == -1)
23571 goto internal_error;
23572 if (ret == 0)
23573 break;
23574 }
23575 }
23576 if (ret == 1)
23577 /* Duplicate found. */
23578 break;
23579 j++;
23580 }
23581 if (j != oldNum) {
23582 /*
23583 * Handle duplicates. Move the duplicate in
23584 * the parent's node-table to the list of
23585 * duplicates.
23586 */
23587 oldNum--;
23588 parBind->nbNodes--;
23589 /*
23590 * Move last old item to pos of duplicate.
23591 */
23592 parNodes[j] = parNodes[oldNum];
23593
23594 if (parBind->nbNodes != oldNum) {
23595 /*
23596 * If new items exist, move last new item to
23597 * last of old items.
23598 */
23599 parNodes[oldNum] =
23600 parNodes[parBind->nbNodes];
23601 }
23602 if (parBind->dupls == NULL((void*)0)) {
23603 parBind->dupls = xmlSchemaItemListCreate();
23604 if (parBind->dupls == NULL((void*)0))
23605 goto internal_error;
23606 }
23607 xmlSchemaItemListAdd(parBind->dupls, parNode);
23608 dupls = (xmlSchemaPSVIIDCNodePtr *)
23609 parBind->dupls->items;
23610 } else {
23611 /*
23612 * Add the node-table entry (node and key-sequence) of
23613 * the child node to the node table of the parent node.
23614 */
23615 if (parBind->nodeTable == NULL((void*)0)) {
23616 parBind->nodeTable = (xmlSchemaPSVIIDCNodePtr *)
23617 xmlMalloc(10 * sizeof(xmlSchemaPSVIIDCNodePtr));
23618 if (parBind->nodeTable == NULL((void*)0)) {
23619 xmlSchemaVErrMemory(NULL((void*)0),
23620 "allocating IDC list of node-table items", NULL((void*)0));
23621 goto internal_error;
23622 }
23623 parBind->sizeNodes = 1;
23624 } else if (parBind->nbNodes >= parBind->sizeNodes) {
23625 parBind->sizeNodes *= 2;
23626 parBind->nodeTable = (xmlSchemaPSVIIDCNodePtr *)
23627 xmlRealloc(parBind->nodeTable, parBind->sizeNodes *
23628 sizeof(xmlSchemaPSVIIDCNodePtr));
23629 if (parBind->nodeTable == NULL((void*)0)) {
23630 xmlSchemaVErrMemory(NULL((void*)0),
23631 "re-allocating IDC list of node-table items", NULL((void*)0));
23632 goto internal_error;
23633 }
23634 }
23635 parNodes = parBind->nodeTable;
23636 /*
23637 * Append the new node-table entry to the 'new node-table
23638 * entries' section.
23639 */
23640 parNodes[parBind->nbNodes++] = node;
23641 }
23642
23643 }
23644
23645 }
23646 } else {
23647 /*
23648 * No binding for the IDC was found: create a new one and
23649 * copy all node-tables.
23650 */
23651 parBind = xmlSchemaIDCNewBinding(bind->definition);
23652 if (parBind == NULL((void*)0))
23653 goto internal_error;
23654
23655 /*
23656 * TODO: Hmm, how to optimize the initial number of
23657 * allocated entries?
23658 */
23659 if (bind->nbNodes != 0) {
23660 /*
23661 * Add all IDC node-table entries.
23662 */
23663 if (! vctxt->psviExposeIDCNodeTables) {
23664 /*
23665 * Just move the entries.
23666 * NOTE: this is quite save here, since
23667 * all the keyref lookups have already been
23668 * performed.
23669 */
23670 parBind->nodeTable = bind->nodeTable;
23671 bind->nodeTable = NULL((void*)0);
23672 parBind->sizeNodes = bind->sizeNodes;
23673 bind->sizeNodes = 0;
23674 parBind->nbNodes = bind->nbNodes;
23675 bind->nbNodes = 0;
23676 } else {
23677 /*
23678 * Copy the entries.
23679 */
23680 parBind->nodeTable = (xmlSchemaPSVIIDCNodePtr *)
23681 xmlMalloc(bind->nbNodes *
23682 sizeof(xmlSchemaPSVIIDCNodePtr));
23683 if (parBind->nodeTable == NULL((void*)0)) {
23684 xmlSchemaVErrMemory(NULL((void*)0),
23685 "allocating an array of IDC node-table "
23686 "items", NULL((void*)0));
23687 xmlSchemaIDCFreeBinding(parBind);
23688 goto internal_error;
23689 }
23690 parBind->sizeNodes = bind->nbNodes;
23691 parBind->nbNodes = bind->nbNodes;
23692 memcpy(parBind->nodeTable, bind->nodeTable,
23693 bind->nbNodes * sizeof(xmlSchemaPSVIIDCNodePtr));
23694 }
23695 }
23696 if (bind->dupls) {
23697 /*
23698 * Move the duplicates.
23699 */
23700 if (parBind->dupls != NULL((void*)0))
23701 xmlSchemaItemListFree(parBind->dupls);
23702 parBind->dupls = bind->dupls;
23703 bind->dupls = NULL((void*)0);
23704 }
23705 if (parTable != NULL((void*)0)) {
23706 if (*parTable == NULL((void*)0))
23707 *parTable = parBind;
23708 else {
23709 parBind->next = *parTable;
23710 *parTable = parBind;
23711 }
23712 }
23713 }
23714
23715next_binding:
23716 bind = bind->next;
23717 }
23718 return (0);
23719
23720internal_error:
23721 return(-1);
23722}
23723
23724/**
23725 * xmlSchemaCheckCVCIDCKeyRef:
23726 * @vctxt: the WXS validation context
23727 * @elemDecl: the element declaration
23728 *
23729 * Check the cvc-idc-keyref constraints.
23730 */
23731static int
23732xmlSchemaCheckCVCIDCKeyRef(xmlSchemaValidCtxtPtr vctxt)
23733{
23734 xmlSchemaIDCMatcherPtr matcher;
23735 xmlSchemaPSVIIDCBindingPtr bind;
23736
23737 matcher = vctxt->inode->idcMatchers;
23738 /*
23739 * Find a keyref.
23740 */
23741 while (matcher != NULL((void*)0)) {
23742 if ((matcher->idcType == XML_SCHEMA_TYPE_IDC_KEYREF) &&
23743 matcher->targets &&
23744 matcher->targets->nbItems)
23745 {
23746 int i, j, k, res, nbFields, hasDupls;
23747 xmlSchemaPSVIIDCKeyPtr *refKeys, *keys;
23748 xmlSchemaPSVIIDCNodePtr refNode = NULL((void*)0);
23749 xmlHashTablePtr table = NULL((void*)0);
23750
23751 nbFields = matcher->aidc->def->nbFields;
23752
23753 /*
23754 * Find the IDC node-table for the referenced IDC key/unique.
23755 */
23756 bind = vctxt->inode->idcTable;
23757 while (bind != NULL((void*)0)) {
23758 if ((xmlSchemaIDCPtr) matcher->aidc->def->ref->item ==
23759 bind->definition)
23760 break;
23761 bind = bind->next;
23762 }
23763 hasDupls = (bind && bind->dupls && bind->dupls->nbItems) ? 1 : 0;
23764 /*
23765 * Search for a matching key-sequences.
23766 */
23767 if (bind) {
23768 table = xmlHashCreate(bind->nbNodes * 2);
23769 for (j = 0; j < bind->nbNodes; j++) {
23770 xmlChar *value;
23771 xmlIDCHashEntryPtr r, e;
23772 keys = bind->nodeTable[j]->keys;
23773 xmlSchemaHashKeySequence(vctxt, &value, keys, nbFields);
23774 e = xmlMalloc(sizeof *e);
23775 e->index = j;
23776 r = xmlHashLookup(table, value);
23777 if (r) {
23778 e->next = r->next;
23779 r->next = e;
23780 } else {
23781 e->next = NULL((void*)0);
23782 xmlHashAddEntry(table, value, e);
23783 }
23784 FREE_AND_NULL(value)if ((value) != ((void*)0)) { xmlFree((xmlChar *) (value)); value
= ((void*)0); }
;
23785 }
23786 }
23787 for (i = 0; i < matcher->targets->nbItems; i++) {
23788 res = 0;
23789 refNode = matcher->targets->items[i];
23790 if (bind != NULL((void*)0)) {
23791 xmlChar *value;
23792 xmlIDCHashEntryPtr e;
23793 refKeys = refNode->keys;
23794 xmlSchemaHashKeySequence(vctxt, &value, refKeys, nbFields);
23795 e = xmlHashLookup(table, value);
23796 FREE_AND_NULL(value)if ((value) != ((void*)0)) { xmlFree((xmlChar *) (value)); value
= ((void*)0); }
;
23797 res = 0;
23798 for (;e; e = e->next) {
23799 keys = bind->nodeTable[e->index]->keys;
23800 for (k = 0; k < nbFields; k++) {
23801 res = xmlSchemaAreValuesEqual(keys[k]->val,
23802 refKeys[k]->val);
23803 if (res == 0)
23804 break;
23805 else if (res == -1) {
23806 return (-1);
23807 }
23808 }
23809 if (res == 1) {
23810 /*
23811 * Match found.
23812 */
23813 break;
23814 }
23815 }
23816 if ((res == 0) && hasDupls) {
23817 /*
23818 * Search in duplicates
23819 */
23820 for (j = 0; j < bind->dupls->nbItems; j++) {
23821 keys = ((xmlSchemaPSVIIDCNodePtr)
23822 bind->dupls->items[j])->keys;
23823 for (k = 0; k < nbFields; k++) {
23824 res = xmlSchemaAreValuesEqual(keys[k]->val,
23825 refKeys[k]->val);
23826 if (res == 0)
23827 break;
23828 else if (res == -1) {
23829 return (-1);
23830 }
23831 }
23832 if (res == 1) {
23833 /*
23834 * Match in duplicates found.
23835 */
23836 xmlChar *str = NULL((void*)0), *strB = NULL((void*)0);
23837 xmlSchemaKeyrefErr(vctxt,
23838 XML_SCHEMAV_CVC_IDC, refNode,
23839 (xmlSchemaTypePtr) matcher->aidc->def,
23840 "More than one match found for "
23841 "key-sequence %s of keyref '%s'",
23842 xmlSchemaFormatIDCKeySequence(vctxt, &str,
23843 refNode->keys, nbFields),
23844 xmlSchemaGetComponentQName(&strB,
23845 matcher->aidc->def));
23846 FREE_AND_NULL(str)if ((str) != ((void*)0)) { xmlFree((xmlChar *) (str)); str = (
(void*)0); }
;
23847 FREE_AND_NULL(strB)if ((strB) != ((void*)0)) { xmlFree((xmlChar *) (strB)); strB
= ((void*)0); }
;
23848 break;
23849 }
23850 }
23851 }
23852 }
23853
23854 if (res == 0) {
23855 xmlChar *str = NULL((void*)0), *strB = NULL((void*)0);
23856 xmlSchemaKeyrefErr(vctxt,
23857 XML_SCHEMAV_CVC_IDC, refNode,
23858 (xmlSchemaTypePtr) matcher->aidc->def,
23859 "No match found for key-sequence %s of keyref '%s'",
23860 xmlSchemaFormatIDCKeySequence(vctxt, &str,
23861 refNode->keys, nbFields),
23862 xmlSchemaGetComponentQName(&strB, matcher->aidc->def));
23863 FREE_AND_NULL(str)if ((str) != ((void*)0)) { xmlFree((xmlChar *) (str)); str = (
(void*)0); }
;
23864 FREE_AND_NULL(strB)if ((strB) != ((void*)0)) { xmlFree((xmlChar *) (strB)); strB
= ((void*)0); }
;
23865 }
23866 }
23867 if (table) {
23868 xmlHashFree(table, xmlFreeIDCHashEntry);
23869 }
23870 }
23871 matcher = matcher->next;
23872 }
23873 /* TODO: Return an error if any error encountered. */
23874 return (0);
23875}
23876
23877/************************************************************************
23878 * *
23879 * XML Reader validation code *
23880 * *
23881 ************************************************************************/
23882
23883static xmlSchemaAttrInfoPtr
23884xmlSchemaGetFreshAttrInfo(xmlSchemaValidCtxtPtr vctxt)
23885{
23886 xmlSchemaAttrInfoPtr iattr;
23887 /*
23888 * Grow/create list of attribute infos.
23889 */
23890 if (vctxt->attrInfos == NULL((void*)0)) {
23891 vctxt->attrInfos = (xmlSchemaAttrInfoPtr *)
23892 xmlMalloc(sizeof(xmlSchemaAttrInfoPtr));
23893 vctxt->sizeAttrInfos = 1;
23894 if (vctxt->attrInfos == NULL((void*)0)) {
23895 xmlSchemaVErrMemory(vctxt,
23896 "allocating attribute info list", NULL((void*)0));
23897 return (NULL((void*)0));
23898 }
23899 } else if (vctxt->sizeAttrInfos <= vctxt->nbAttrInfos) {
23900 vctxt->sizeAttrInfos++;
23901 vctxt->attrInfos = (xmlSchemaAttrInfoPtr *)
23902 xmlRealloc(vctxt->attrInfos,
23903 vctxt->sizeAttrInfos * sizeof(xmlSchemaAttrInfoPtr));
23904 if (vctxt->attrInfos == NULL((void*)0)) {
23905 xmlSchemaVErrMemory(vctxt,
23906 "re-allocating attribute info list", NULL((void*)0));
23907 return (NULL((void*)0));
23908 }
23909 } else {
23910 iattr = vctxt->attrInfos[vctxt->nbAttrInfos++];
23911 if (iattr->localName != NULL((void*)0)) {
23912 VERROR_INT("xmlSchemaGetFreshAttrInfo",xmlSchemaInternalErr((xmlSchemaAbstractCtxtPtr) vctxt, "xmlSchemaGetFreshAttrInfo"
, "attr info not cleared");
23913 "attr info not cleared")xmlSchemaInternalErr((xmlSchemaAbstractCtxtPtr) vctxt, "xmlSchemaGetFreshAttrInfo"
, "attr info not cleared");
;
23914 return (NULL((void*)0));
23915 }
23916 iattr->nodeType = XML_ATTRIBUTE_NODE;
23917 return (iattr);
23918 }
23919 /*
23920 * Create an attribute info.
23921 */
23922 iattr = (xmlSchemaAttrInfoPtr)
23923 xmlMalloc(sizeof(xmlSchemaAttrInfo));
23924 if (iattr == NULL((void*)0)) {
23925 xmlSchemaVErrMemory(vctxt, "creating new attribute info", NULL((void*)0));
23926 return (NULL((void*)0));
23927 }
23928 memset(iattr, 0, sizeof(xmlSchemaAttrInfo));
23929 iattr->nodeType = XML_ATTRIBUTE_NODE;
23930 vctxt->attrInfos[vctxt->nbAttrInfos++] = iattr;
23931
23932 return (iattr);
23933}
23934
23935static int
23936xmlSchemaValidatorPushAttribute(xmlSchemaValidCtxtPtr vctxt,
23937 xmlNodePtr attrNode,
23938 int nodeLine,
23939 const xmlChar *localName,
23940 const xmlChar *nsName,
23941 int ownedNames,
23942 xmlChar *value,
23943 int ownedValue)
23944{
23945 xmlSchemaAttrInfoPtr attr;
23946
23947 attr = xmlSchemaGetFreshAttrInfo(vctxt);
23948 if (attr == NULL((void*)0)) {
23949 VERROR_INT("xmlSchemaPushAttribute",xmlSchemaInternalErr((xmlSchemaAbstractCtxtPtr) vctxt, "xmlSchemaPushAttribute"
, "calling xmlSchemaGetFreshAttrInfo()");
23950 "calling xmlSchemaGetFreshAttrInfo()")xmlSchemaInternalErr((xmlSchemaAbstractCtxtPtr) vctxt, "xmlSchemaPushAttribute"
, "calling xmlSchemaGetFreshAttrInfo()");
;
23951 return (-1);
23952 }
23953 attr->node = attrNode;
23954 attr->nodeLine = nodeLine;
23955 attr->state = XML_SCHEMAS_ATTR_UNKNOWN1;
23956 attr->localName = localName;
23957 attr->nsName = nsName;
23958 if (ownedNames)
23959 attr->flags |= XML_SCHEMA_NODE_INFO_FLAG_OWNED_NAMES1<<0;
23960 /*
23961 * Evaluate if it's an XSI attribute.
23962 */
23963 if (nsName != NULL((void*)0)) {
23964 if (xmlStrEqual(localName, BAD_CAST(xmlChar *) "nil")) {
23965 if (xmlStrEqual(attr->nsName, xmlSchemaInstanceNs)) {
23966 attr->metaType = XML_SCHEMA_ATTR_INFO_META_XSI_NIL2;
23967 }
23968 } else if (xmlStrEqual(localName, BAD_CAST(xmlChar *) "type")) {
23969 if (xmlStrEqual(attr->nsName, xmlSchemaInstanceNs)) {
23970 attr->metaType = XML_SCHEMA_ATTR_INFO_META_XSI_TYPE1;
23971 }
23972 } else if (xmlStrEqual(localName, BAD_CAST(xmlChar *) "schemaLocation")) {
23973 if (xmlStrEqual(attr->nsName, xmlSchemaInstanceNs)) {
23974 attr->metaType = XML_SCHEMA_ATTR_INFO_META_XSI_SCHEMA_LOC3;
23975 }
23976 } else if (xmlStrEqual(localName, BAD_CAST(xmlChar *) "noNamespaceSchemaLocation")) {
23977 if (xmlStrEqual(attr->nsName, xmlSchemaInstanceNs)) {
23978 attr->metaType = XML_SCHEMA_ATTR_INFO_META_XSI_NO_NS_SCHEMA_LOC4;
23979 }
23980 } else if (xmlStrEqual(attr->nsName, xmlNamespaceNs)) {
23981 attr->metaType = XML_SCHEMA_ATTR_INFO_META_XMLNS5;
23982 }
23983 }
23984 attr->value = value;
23985 if (ownedValue)
23986 attr->flags |= XML_SCHEMA_NODE_INFO_FLAG_OWNED_VALUES1<<1;
23987 if (attr->metaType != 0)
23988 attr->state = XML_SCHEMAS_ATTR_META17;
23989 return (0);
23990}
23991
23992/**
23993 * xmlSchemaClearElemInfo:
23994 * @vctxt: the WXS validation context
23995 * @ielem: the element information item
23996 */
23997static void
23998xmlSchemaClearElemInfo(xmlSchemaValidCtxtPtr vctxt,
23999 xmlSchemaNodeInfoPtr ielem)
24000{
24001 ielem->hasKeyrefs = 0;
24002 ielem->appliedXPath = 0;
24003 if (ielem->flags & XML_SCHEMA_NODE_INFO_FLAG_OWNED_NAMES1<<0) {
24004 FREE_AND_NULL(ielem->localName)if ((ielem->localName) != ((void*)0)) { xmlFree((xmlChar *
) (ielem->localName)); ielem->localName = ((void*)0); }
;
24005 FREE_AND_NULL(ielem->nsName)if ((ielem->nsName) != ((void*)0)) { xmlFree((xmlChar *) (
ielem->nsName)); ielem->nsName = ((void*)0); }
;
24006 } else {
24007 ielem->localName = NULL((void*)0);
24008 ielem->nsName = NULL((void*)0);
24009 }
24010 if (ielem->flags & XML_SCHEMA_NODE_INFO_FLAG_OWNED_VALUES1<<1) {
24011 FREE_AND_NULL(ielem->value)if ((ielem->value) != ((void*)0)) { xmlFree((xmlChar *) (ielem
->value)); ielem->value = ((void*)0); }
;
24012 } else {
24013 ielem->value = NULL((void*)0);
24014 }
24015 if (ielem->val != NULL((void*)0)) {
24016 /*
24017 * PSVI TODO: Be careful not to free it when the value is
24018 * exposed via PSVI.
24019 */
24020 xmlSchemaFreeValue(ielem->val);
24021 ielem->val = NULL((void*)0);
24022 }
24023 if (ielem->idcMatchers != NULL((void*)0)) {
24024 /*
24025 * REVISIT OPTIMIZE TODO: Use a pool of IDC matchers.
24026 * Does it work?
24027 */
24028 xmlSchemaIDCReleaseMatcherList(vctxt, ielem->idcMatchers);
24029#if 0
24030 xmlSchemaIDCFreeMatcherList(ielem->idcMatchers);
24031#endif
24032 ielem->idcMatchers = NULL((void*)0);
24033 }
24034 if (ielem->idcTable != NULL((void*)0)) {
24035 /*
24036 * OPTIMIZE TODO: Use a pool of IDC tables??.
24037 */
24038 xmlSchemaIDCFreeIDCTable(ielem->idcTable);
24039 ielem->idcTable = NULL((void*)0);
24040 }
24041 if (ielem->regexCtxt != NULL((void*)0)) {
24042 xmlRegFreeExecCtxt(ielem->regexCtxt);
24043 ielem->regexCtxt = NULL((void*)0);
24044 }
24045 if (ielem->nsBindings != NULL((void*)0)) {
24046 xmlFree((xmlChar **)ielem->nsBindings);
24047 ielem->nsBindings = NULL((void*)0);
24048 ielem->nbNsBindings = 0;
24049 ielem->sizeNsBindings = 0;
24050 }
24051}
24052
24053/**
24054 * xmlSchemaGetFreshElemInfo:
24055 * @vctxt: the schema validation context
24056 *
24057 * Creates/reuses and initializes the element info item for
24058 * the current tree depth.
24059 *
24060 * Returns the element info item or NULL on API or internal errors.
24061 */
24062static xmlSchemaNodeInfoPtr
24063xmlSchemaGetFreshElemInfo(xmlSchemaValidCtxtPtr vctxt)
24064{
24065 xmlSchemaNodeInfoPtr info = NULL((void*)0);
24066
24067 if (vctxt->depth > vctxt->sizeElemInfos) {
24068 VERROR_INT("xmlSchemaGetFreshElemInfo",xmlSchemaInternalErr((xmlSchemaAbstractCtxtPtr) vctxt, "xmlSchemaGetFreshElemInfo"
, "inconsistent depth encountered");
24069 "inconsistent depth encountered")xmlSchemaInternalErr((xmlSchemaAbstractCtxtPtr) vctxt, "xmlSchemaGetFreshElemInfo"
, "inconsistent depth encountered");
;
24070 return (NULL((void*)0));
24071 }
24072 if (vctxt->elemInfos == NULL((void*)0)) {
24073 vctxt->elemInfos = (xmlSchemaNodeInfoPtr *)
24074 xmlMalloc(10 * sizeof(xmlSchemaNodeInfoPtr));
24075 if (vctxt->elemInfos == NULL((void*)0)) {
24076 xmlSchemaVErrMemory(vctxt,
24077 "allocating the element info array", NULL((void*)0));
24078 return (NULL((void*)0));
24079 }
24080 memset(vctxt->elemInfos, 0, 10 * sizeof(xmlSchemaNodeInfoPtr));
24081 vctxt->sizeElemInfos = 10;
24082 } else if (vctxt->sizeElemInfos <= vctxt->depth) {
24083 int i = vctxt->sizeElemInfos;
24084
24085 vctxt->sizeElemInfos *= 2;
24086 vctxt->elemInfos = (xmlSchemaNodeInfoPtr *)
24087 xmlRealloc(vctxt->elemInfos, vctxt->sizeElemInfos *
24088 sizeof(xmlSchemaNodeInfoPtr));
24089 if (vctxt->elemInfos == NULL((void*)0)) {
24090 xmlSchemaVErrMemory(vctxt,
24091 "re-allocating the element info array", NULL((void*)0));
24092 return (NULL((void*)0));
24093 }
24094 /*
24095 * We need the new memory to be NULLed.
24096 * TODO: Use memset instead?
24097 */
24098 for (; i < vctxt->sizeElemInfos; i++)
24099 vctxt->elemInfos[i] = NULL((void*)0);
24100 } else
24101 info = vctxt->elemInfos[vctxt->depth];
24102
24103 if (info == NULL((void*)0)) {
24104 info = (xmlSchemaNodeInfoPtr)
24105 xmlMalloc(sizeof(xmlSchemaNodeInfo));
24106 if (info == NULL((void*)0)) {
24107 xmlSchemaVErrMemory(vctxt,
24108 "allocating an element info", NULL((void*)0));
24109 return (NULL((void*)0));
24110 }
24111 vctxt->elemInfos[vctxt->depth] = info;
24112 } else {
24113 if (info->localName != NULL((void*)0)) {
24114 VERROR_INT("xmlSchemaGetFreshElemInfo",xmlSchemaInternalErr((xmlSchemaAbstractCtxtPtr) vctxt, "xmlSchemaGetFreshElemInfo"
, "elem info has not been cleared");
24115 "elem info has not been cleared")xmlSchemaInternalErr((xmlSchemaAbstractCtxtPtr) vctxt, "xmlSchemaGetFreshElemInfo"
, "elem info has not been cleared");
;
24116 return (NULL((void*)0));
24117 }
24118 }
24119 memset(info, 0, sizeof(xmlSchemaNodeInfo));
24120 info->nodeType = XML_ELEMENT_NODE;
24121 info->depth = vctxt->depth;
24122
24123 return (info);
24124}
24125
24126#define ACTIVATE_ATTRIBUTE(item)vctxt->inode = (xmlSchemaNodeInfoPtr) item; vctxt->inode = (xmlSchemaNodeInfoPtr) item;
24127#define ACTIVATE_ELEMvctxt->inode = vctxt->elemInfos[vctxt->depth]; vctxt->inode = vctxt->elemInfos[vctxt->depth];
24128#define ACTIVATE_PARENT_ELEMvctxt->inode = vctxt->elemInfos[vctxt->depth -1]; vctxt->inode = vctxt->elemInfos[vctxt->depth -1];
24129
24130static int
24131xmlSchemaValidateFacets(xmlSchemaAbstractCtxtPtr actxt,
24132 xmlNodePtr node,
24133 xmlSchemaTypePtr type,
24134 xmlSchemaValType valType,
24135 const xmlChar * value,
24136 xmlSchemaValPtr val,
24137 unsigned long length,
24138 int fireErrors)
24139{
24140 int ret, error = 0, found;
24141
24142 xmlSchemaTypePtr tmpType;
24143 xmlSchemaFacetLinkPtr facetLink;
24144 xmlSchemaFacetPtr facet;
24145 unsigned long len = 0;
24146 xmlSchemaWhitespaceValueType ws;
24147
24148 /*
24149 * In Libxml2, derived built-in types have currently no explicit facets.
24150 */
24151 if (type->type == XML_SCHEMA_TYPE_BASIC)
24152 return (0);
24153
24154 /*
24155 * NOTE: Do not jump away, if the facetSet of the given type is
24156 * empty: until now, "pattern" and "enumeration" facets of the
24157 * *base types* need to be checked as well.
24158 */
24159 if (type->facetSet == NULL((void*)0))
24160 goto pattern_and_enum;
24161
24162 if (! WXS_IS_ATOMIC(type)(type->flags & 1 << 8)) {
24163 if (WXS_IS_LIST(type)(type->flags & 1 << 6))
24164 goto WXS_IS_LIST;
24165 else
24166 goto pattern_and_enum;
24167 }
24168
24169 /*
24170 * Whitespace handling is only of importance for string-based
24171 * types.
24172 */
24173 tmpType = xmlSchemaGetPrimitiveType(type);
24174 if ((tmpType->builtInType == XML_SCHEMAS_STRING) ||
24175 WXS_IS_ANY_SIMPLE_TYPE(tmpType)(((tmpType)->type == XML_SCHEMA_TYPE_BASIC) && ((tmpType
)->builtInType == XML_SCHEMAS_ANYSIMPLETYPE))
) {
24176 ws = xmlSchemaGetWhiteSpaceFacetValue(type);
24177 } else
24178 ws = XML_SCHEMA_WHITESPACE_COLLAPSE;
24179
24180 /*
24181 * If the value was not computed (for string or
24182 * anySimpleType based types), then use the provided
24183 * type.
24184 */
24185 if (val != NULL((void*)0))
24186 valType = xmlSchemaGetValType(val);
24187
24188 ret = 0;
24189 for (facetLink = type->facetSet; facetLink != NULL((void*)0);
24190 facetLink = facetLink->next) {
24191 /*
24192 * Skip the pattern "whiteSpace": it is used to
24193 * format the character content beforehand.
24194 */
24195 switch (facetLink->facet->type) {
24196 case XML_SCHEMA_FACET_WHITESPACE:
24197 case XML_SCHEMA_FACET_PATTERN:
24198 case XML_SCHEMA_FACET_ENUMERATION:
24199 continue;
24200 case XML_SCHEMA_FACET_LENGTH:
24201 case XML_SCHEMA_FACET_MINLENGTH:
24202 case XML_SCHEMA_FACET_MAXLENGTH:
24203 ret = xmlSchemaValidateLengthFacetWhtsp(facetLink->facet,
24204 valType, value, val, &len, ws);
24205 break;
24206 default:
24207 ret = xmlSchemaValidateFacetWhtsp(facetLink->facet, ws,
24208 valType, value, val, ws);
24209 break;
24210 }
24211 if (ret < 0) {
24212 AERROR_INT("xmlSchemaValidateFacets",xmlSchemaInternalErr(actxt, "xmlSchemaValidateFacets", "validating against a atomic type facet"
);
24213 "validating against a atomic type facet")xmlSchemaInternalErr(actxt, "xmlSchemaValidateFacets", "validating against a atomic type facet"
);
;
24214 return (-1);
24215 } else if (ret > 0) {
24216 if (fireErrors)
24217 xmlSchemaFacetErr(actxt, ret, node,
24218 value, len, type, facetLink->facet, NULL((void*)0), NULL((void*)0), NULL((void*)0));
24219 else
24220 return (ret);
24221 if (error == 0)
24222 error = ret;
24223 }
24224 ret = 0;
24225 }
24226
24227WXS_IS_LIST:
24228 if (! WXS_IS_LIST(type)(type->flags & 1 << 6))
24229 goto pattern_and_enum;
24230 /*
24231 * "length", "minLength" and "maxLength" of list types.
24232 */
24233 ret = 0;
24234 for (facetLink = type->facetSet; facetLink != NULL((void*)0);
24235 facetLink = facetLink->next) {
24236
24237 switch (facetLink->facet->type) {
24238 case XML_SCHEMA_FACET_LENGTH:
24239 case XML_SCHEMA_FACET_MINLENGTH:
24240 case XML_SCHEMA_FACET_MAXLENGTH:
24241 ret = xmlSchemaValidateListSimpleTypeFacet(facetLink->facet,
24242 value, length, NULL((void*)0));
24243 break;
24244 default:
24245 continue;
24246 }
24247 if (ret < 0) {
24248 AERROR_INT("xmlSchemaValidateFacets",xmlSchemaInternalErr(actxt, "xmlSchemaValidateFacets", "validating against a list type facet"
);
24249 "validating against a list type facet")xmlSchemaInternalErr(actxt, "xmlSchemaValidateFacets", "validating against a list type facet"
);
;
24250 return (-1);
24251 } else if (ret > 0) {
24252 if (fireErrors)
24253 xmlSchemaFacetErr(actxt, ret, node,
24254 value, length, type, facetLink->facet, NULL((void*)0), NULL((void*)0), NULL((void*)0));
24255 else
24256 return (ret);
24257 if (error == 0)
24258 error = ret;
24259 }
24260 ret = 0;
24261 }
24262
24263pattern_and_enum:
24264 found = 0;
24265 /*
24266 * Process enumerations. Facet values are in the value space
24267 * of the defining type's base type. This seems to be a bug in the
24268 * XML Schema 1.0 spec. Use the whitespace type of the base type.
24269 * Only the first set of enumerations in the ancestor-or-self axis
24270 * is used for validation.
24271 */
24272 ret = 0;
24273 tmpType = type;
24274 do {
24275 for (facet = tmpType->facets; facet != NULL((void*)0); facet = facet->next) {
24276 if (facet->type != XML_SCHEMA_FACET_ENUMERATION)
24277 continue;
24278 found = 1;
24279 ret = xmlSchemaAreValuesEqual(facet->val, val);
24280 if (ret == 1)
24281 break;
24282 else if (ret < 0) {
24283 AERROR_INT("xmlSchemaValidateFacets",xmlSchemaInternalErr(actxt, "xmlSchemaValidateFacets", "validating against an enumeration facet"
);
24284 "validating against an enumeration facet")xmlSchemaInternalErr(actxt, "xmlSchemaValidateFacets", "validating against an enumeration facet"
);
;
24285 return (-1);
24286 }
24287 }
24288 if (ret != 0)
24289 break;
24290 /*
24291 * Break on the first set of enumerations. Any additional
24292 * enumerations which might be existent on the ancestors
24293 * of the current type are restricted by this set; thus
24294 * *must* *not* be taken into account.
24295 */
24296 if (found)
24297 break;
24298 tmpType = tmpType->baseType;
24299 } while ((tmpType != NULL((void*)0)) &&
24300 (tmpType->type != XML_SCHEMA_TYPE_BASIC));
24301 if (found && (ret == 0)) {
24302 ret = XML_SCHEMAV_CVC_ENUMERATION_VALID;
24303 if (fireErrors) {
24304 xmlSchemaFacetErr(actxt, ret, node,
24305 value, 0, type, NULL((void*)0), NULL((void*)0), NULL((void*)0), NULL((void*)0));
24306 } else
24307 return (ret);
24308 if (error == 0)
24309 error = ret;
24310 }
24311
24312 /*
24313 * Process patters. Pattern facets are ORed at type level
24314 * and ANDed if derived. Walk the base type axis.
24315 */
24316 tmpType = type;
24317 facet = NULL((void*)0);
24318 do {
24319 found = 0;
24320 for (facetLink = tmpType->facetSet; facetLink != NULL((void*)0);
24321 facetLink = facetLink->next) {
24322 if (facetLink->facet->type != XML_SCHEMA_FACET_PATTERN)
24323 continue;
24324 found = 1;
24325 /*
24326 * NOTE that for patterns, @value needs to be the
24327 * normalized value.
24328 */
24329 ret = xmlRegexpExec(facetLink->facet->regexp, value);
24330 if (ret == 1)
24331 break;
24332 else if (ret < 0) {
24333 AERROR_INT("xmlSchemaValidateFacets",xmlSchemaInternalErr(actxt, "xmlSchemaValidateFacets", "validating against a pattern facet"
);
24334 "validating against a pattern facet")xmlSchemaInternalErr(actxt, "xmlSchemaValidateFacets", "validating against a pattern facet"
);
;
24335 return (-1);
24336 } else {
24337 /*
24338 * Save the last non-validating facet.
24339 */
24340 facet = facetLink->facet;
24341 }
24342 }
24343 if (found && (ret != 1)) {
24344 ret = XML_SCHEMAV_CVC_PATTERN_VALID;
24345 if (fireErrors) {
24346 xmlSchemaFacetErr(actxt, ret, node,
24347 value, 0, type, facet, NULL((void*)0), NULL((void*)0), NULL((void*)0));
24348 } else
24349 return (ret);
24350 if (error == 0)
24351 error = ret;
24352 break;
24353 }
24354 tmpType = tmpType->baseType;
24355 } while ((tmpType != NULL((void*)0)) && (tmpType->type != XML_SCHEMA_TYPE_BASIC));
24356
24357 return (error);
24358}
24359
24360static xmlChar *
24361xmlSchemaNormalizeValue(xmlSchemaTypePtr type,
24362 const xmlChar *value)
24363{
24364 switch (xmlSchemaGetWhiteSpaceFacetValue(type)) {
24365 case XML_SCHEMA_WHITESPACE_COLLAPSE:
24366 return (xmlSchemaCollapseString(value));
24367 case XML_SCHEMA_WHITESPACE_REPLACE:
24368 return (xmlSchemaWhiteSpaceReplace(value));
24369 default:
24370 return (NULL((void*)0));
24371 }
24372}
24373
24374static int
24375xmlSchemaValidateQName(xmlSchemaValidCtxtPtr vctxt,
24376 const xmlChar *value,
24377 xmlSchemaValPtr *val,
24378 int valNeeded)
24379{
24380 int ret;
24381 xmlChar *stripped;
24382 const xmlChar *nsName;
24383 xmlChar *local, *prefix = NULL((void*)0);
24384
24385 ret = xmlValidateQName(value, 1);
24386 if (ret != 0) {
24387 if (ret == -1) {
24388 VERROR_INT("xmlSchemaValidateQName",xmlSchemaInternalErr((xmlSchemaAbstractCtxtPtr) vctxt, "xmlSchemaValidateQName"
, "calling xmlValidateQName()");
24389 "calling xmlValidateQName()")xmlSchemaInternalErr((xmlSchemaAbstractCtxtPtr) vctxt, "xmlSchemaValidateQName"
, "calling xmlValidateQName()");
;
24390 return (-1);
24391 }
24392 return( XML_SCHEMAV_CVC_DATATYPE_VALID_1_2_1);
24393 }
24394 /*
24395 * NOTE: xmlSplitQName2 will always return a duplicated
24396 * strings.
24397 */
24398 /* TODO: Export and use xmlSchemaStrip instead */
24399 stripped = xmlSchemaCollapseString(value);
24400 local = xmlSplitQName2(stripped ? stripped : value, &prefix);
24401 xmlFree(stripped);
24402 if (local == NULL((void*)0))
24403 local = xmlStrdup(value);
24404 /*
24405 * OPTIMIZE TODO: Use flags for:
24406 * - is there any namespace binding?
24407 * - is there a default namespace?
24408 */
24409 nsName = xmlSchemaLookupNamespace(vctxt, prefix);
24410
24411 if (prefix != NULL((void*)0)) {
24412 xmlFree(prefix);
24413 /*
24414 * A namespace must be found if the prefix is
24415 * NOT NULL.
24416 */
24417 if (nsName == NULL((void*)0)) {
24418 ret = XML_SCHEMAV_CVC_DATATYPE_VALID_1_2_1;
24419 xmlSchemaCustomErr(ACTXT_CAST(xmlSchemaAbstractCtxtPtr) vctxt, ret, NULL((void*)0),
24420 WXS_BASIC_CAST(xmlSchemaBasicItemPtr) xmlSchemaGetBuiltInType(XML_SCHEMAS_QNAME),
24421 "The QName value '%s' has no "
24422 "corresponding namespace declaration in "
24423 "scope", value, NULL((void*)0));
24424 if (local != NULL((void*)0))
24425 xmlFree(local);
24426 return (ret);
24427 }
24428 }
24429 if (valNeeded && val) {
24430 if (nsName != NULL((void*)0))
24431 *val = xmlSchemaNewQNameValue(
24432 BAD_CAST(xmlChar *) xmlStrdup(nsName), BAD_CAST(xmlChar *) local);
24433 else
24434 *val = xmlSchemaNewQNameValue(NULL((void*)0),
24435 BAD_CAST(xmlChar *) local);
24436 } else
24437 xmlFree(local);
24438 return (0);
24439}
24440
24441/*
24442* cvc-simple-type
24443*/
24444static int
24445xmlSchemaVCheckCVCSimpleType(xmlSchemaAbstractCtxtPtr actxt,
24446 xmlNodePtr node,
24447 xmlSchemaTypePtr type,
24448 const xmlChar *value,
24449 xmlSchemaValPtr *retVal,
24450 int fireErrors,
24451 int normalize,
24452 int isNormalized)
24453{
24454 int ret = 0, valNeeded = (retVal) ? 1 : 0;
24455 xmlSchemaValPtr val = NULL((void*)0);
24456 /* xmlSchemaWhitespaceValueType ws; */
24457 xmlChar *normValue = NULL((void*)0);
24458
24459#define NORMALIZE(atype)if ((! isNormalized) && (normalize || (type->flags
& 1 << 28))) { normValue = xmlSchemaNormalizeValue
(atype, value); if (normValue != ((void*)0)) value = normValue
; isNormalized = 1; }
\
24460 if ((! isNormalized) && \
24461 (normalize || (type->flags & XML_SCHEMAS_TYPE_NORMVALUENEEDED1 << 28))) { \
24462 normValue = xmlSchemaNormalizeValue(atype, value); \
24463 if (normValue != NULL((void*)0)) \
24464 value = normValue; \
24465 isNormalized = 1; \
24466 }
24467
24468 if ((retVal != NULL((void*)0)) && (*retVal != NULL((void*)0))) {
24469 xmlSchemaFreeValue(*retVal);
24470 *retVal = NULL((void*)0);
24471 }
24472 /*
24473 * 3.14.4 Simple Type Definition Validation Rules
24474 * Validation Rule: String Valid
24475 */
24476 /*
24477 * 1 It is schema-valid with respect to that definition as defined
24478 * by Datatype Valid in [XML Schemas: Datatypes].
24479 */
24480 /*
24481 * 2.1 If The definition is ENTITY or is validly derived from ENTITY given
24482 * the empty set, as defined in Type Derivation OK (Simple) ($3.14.6), then
24483 * the string must be a `declared entity name`.
24484 */
24485 /*
24486 * 2.2 If The definition is ENTITIES or is validly derived from ENTITIES
24487 * given the empty set, as defined in Type Derivation OK (Simple) ($3.14.6),
24488 * then every whitespace-delimited substring of the string must be a `declared
24489 * entity name`.
24490 */
24491 /*
24492 * 2.3 otherwise no further condition applies.
24493 */
24494 if ((! valNeeded) && (type->flags & XML_SCHEMAS_TYPE_FACETSNEEDVALUE1 << 21))
24495 valNeeded = 1;
24496 if (value == NULL((void*)0))
24497 value = BAD_CAST(xmlChar *) "";
24498 if (WXS_IS_ANY_SIMPLE_TYPE(type)(((type)->type == XML_SCHEMA_TYPE_BASIC) && ((type
)->builtInType == XML_SCHEMAS_ANYSIMPLETYPE))
|| WXS_IS_ATOMIC(type)(type->flags & 1 << 8)) {
24499 xmlSchemaTypePtr biType; /* The built-in type. */
24500 /*
24501 * SPEC (1.2.1) "if {variety} is `atomic` then the string must `match`
24502 * a literal in the `lexical space` of {base type definition}"
24503 */
24504 /*
24505 * Whitespace-normalize.
24506 */
24507 NORMALIZE(type)if ((! isNormalized) && (normalize || (type->flags
& 1 << 28))) { normValue = xmlSchemaNormalizeValue
(type, value); if (normValue != ((void*)0)) value = normValue
; isNormalized = 1; }
;
24508 if (type->type != XML_SCHEMA_TYPE_BASIC) {
24509 /*
24510 * Get the built-in type.
24511 */
24512 biType = type->baseType;
24513 while ((biType != NULL((void*)0)) &&
24514 (biType->type != XML_SCHEMA_TYPE_BASIC))
24515 biType = biType->baseType;
24516
24517 if (biType == NULL((void*)0)) {
24518 AERROR_INT("xmlSchemaVCheckCVCSimpleType",xmlSchemaInternalErr(actxt, "xmlSchemaVCheckCVCSimpleType", "could not get the built-in type"
);
24519 "could not get the built-in type")xmlSchemaInternalErr(actxt, "xmlSchemaVCheckCVCSimpleType", "could not get the built-in type"
);
;
24520 goto internal_error;
24521 }
24522 } else
24523 biType = type;
24524 /*
24525 * NOTATIONs need to be processed here, since they need
24526 * to lookup in the hashtable of NOTATION declarations of the schema.
24527 */
24528 if (actxt->type == XML_SCHEMA_CTXT_VALIDATOR2) {
24529 switch (biType->builtInType) {
24530 case XML_SCHEMAS_NOTATION:
24531 ret = xmlSchemaValidateNotation(
24532 (xmlSchemaValidCtxtPtr) actxt,
24533 ((xmlSchemaValidCtxtPtr) actxt)->schema,
24534 NULL((void*)0), value, &val, valNeeded);
24535 break;
24536 case XML_SCHEMAS_QNAME:
24537 ret = xmlSchemaValidateQName((xmlSchemaValidCtxtPtr) actxt,
24538 value, &val, valNeeded);
24539 break;
24540 default:
24541 /* ws = xmlSchemaGetWhiteSpaceFacetValue(type); */
24542 if (valNeeded)
24543 ret = xmlSchemaValPredefTypeNodeNoNorm(biType,
24544 value, &val, node);
24545 else
24546 ret = xmlSchemaValPredefTypeNodeNoNorm(biType,
24547 value, NULL((void*)0), node);
24548 break;
24549 }
24550 } else if (actxt->type == XML_SCHEMA_CTXT_PARSER1) {
24551 switch (biType->builtInType) {
24552 case XML_SCHEMAS_NOTATION:
24553 ret = xmlSchemaValidateNotation(NULL((void*)0),
24554 ((xmlSchemaParserCtxtPtr) actxt)->schema, node,
24555 value, &val, valNeeded);
24556 break;
24557 default:
24558 /* ws = xmlSchemaGetWhiteSpaceFacetValue(type); */
24559 if (valNeeded)
24560 ret = xmlSchemaValPredefTypeNodeNoNorm(biType,
24561 value, &val, node);
24562 else
24563 ret = xmlSchemaValPredefTypeNodeNoNorm(biType,
24564 value, NULL((void*)0), node);
24565 break;
24566 }
24567 } else {
24568 /*
24569 * Validation via a public API is not implemented yet.
24570 */
24571 TODO(*__xmlGenericError())((*__xmlGenericErrorContext()), "Unimplemented block at %s:%d\n"
, "xmlschemas.c", 24571);
24572 goto internal_error;
24573 }
24574 if (ret != 0) {
24575 if (ret < 0) {
24576 AERROR_INT("xmlSchemaVCheckCVCSimpleType",xmlSchemaInternalErr(actxt, "xmlSchemaVCheckCVCSimpleType", "validating against a built-in type"
);
24577 "validating against a built-in type")xmlSchemaInternalErr(actxt, "xmlSchemaVCheckCVCSimpleType", "validating against a built-in type"
);
;
24578 goto internal_error;
24579 }
24580 if (WXS_IS_LIST(type)(type->flags & 1 << 6))
24581 ret = XML_SCHEMAV_CVC_DATATYPE_VALID_1_2_2;
24582 else
24583 ret = XML_SCHEMAV_CVC_DATATYPE_VALID_1_2_1;
24584 }
24585 if ((ret == 0) && (type->flags & XML_SCHEMAS_TYPE_HAS_FACETS1 << 27)) {
24586 /*
24587 * Check facets.
24588 */
24589 ret = xmlSchemaValidateFacets(actxt, node, type,
24590 (xmlSchemaValType) biType->builtInType, value, val,
24591 0, fireErrors);
24592 if (ret != 0) {
24593 if (ret < 0) {
24594 AERROR_INT("xmlSchemaVCheckCVCSimpleType",xmlSchemaInternalErr(actxt, "xmlSchemaVCheckCVCSimpleType", "validating facets of atomic simple type"
);
24595 "validating facets of atomic simple type")xmlSchemaInternalErr(actxt, "xmlSchemaVCheckCVCSimpleType", "validating facets of atomic simple type"
);
;
24596 goto internal_error;
24597 }
24598 if (WXS_IS_LIST(type)(type->flags & 1 << 6))
24599 ret = XML_SCHEMAV_CVC_DATATYPE_VALID_1_2_2;
24600 else
24601 ret = XML_SCHEMAV_CVC_DATATYPE_VALID_1_2_1;
24602 }
24603 }
24604 else if (fireErrors && (ret > 0))
24605 xmlSchemaSimpleTypeErr(actxt, ret, node, value, type, 1);
24606 } else if (WXS_IS_LIST(type)(type->flags & 1 << 6)) {
24607
24608 xmlSchemaTypePtr itemType;
24609 const xmlChar *cur, *end;
24610 xmlChar *tmpValue = NULL((void*)0);
24611 unsigned long len = 0;
24612 xmlSchemaValPtr prevVal = NULL((void*)0), curVal = NULL((void*)0);
24613 /* 1.2.2 if {variety} is `list` then the string must be a sequence
24614 * of white space separated tokens, each of which `match`es a literal
24615 * in the `lexical space` of {item type definition}
24616 */
24617 /*
24618 * Note that XML_SCHEMAS_TYPE_NORMVALUENEEDED will be set if
24619 * the list type has an enum or pattern facet.
24620 */
24621 NORMALIZE(type)if ((! isNormalized) && (normalize || (type->flags
& 1 << 28))) { normValue = xmlSchemaNormalizeValue
(type, value); if (normValue != ((void*)0)) value = normValue
; isNormalized = 1; }
;
24622 /*
24623 * VAL TODO: Optimize validation of empty values.
24624 * VAL TODO: We do not have computed values for lists.
24625 */
24626 itemType = WXS_LIST_ITEMTYPE(type)(type)->subtypes;
24627 cur = value;
24628 do {
24629 while (IS_BLANK_CH(*cur)(((*cur) == 0x20) || ((0x9 <= (*cur)) && ((*cur) <=
0xa)) || ((*cur) == 0xd))
)
24630 cur++;
24631 end = cur;
24632 while ((*end != 0) && (!(IS_BLANK_CH(*end)(((*end) == 0x20) || ((0x9 <= (*end)) && ((*end) <=
0xa)) || ((*end) == 0xd))
)))
24633 end++;
24634 if (end == cur)
24635 break;
24636 tmpValue = xmlStrndup(cur, end - cur);
24637 len++;
24638
24639 if (valNeeded)
24640 ret = xmlSchemaVCheckCVCSimpleType(actxt, node, itemType,
24641 tmpValue, &curVal, fireErrors, 0, 1);
24642 else
24643 ret = xmlSchemaVCheckCVCSimpleType(actxt, node, itemType,
24644 tmpValue, NULL((void*)0), fireErrors, 0, 1);
24645 FREE_AND_NULL(tmpValue)if ((tmpValue) != ((void*)0)) { xmlFree((xmlChar *) (tmpValue
)); tmpValue = ((void*)0); }
;
24646 if (curVal != NULL((void*)0)) {
24647 /*
24648 * Add to list of computed values.
24649 */
24650 if (val == NULL((void*)0))
24651 val = curVal;
24652 else
24653 xmlSchemaValueAppend(prevVal, curVal);
24654 prevVal = curVal;
24655 curVal = NULL((void*)0);
24656 }
24657 if (ret != 0) {
24658 if (ret < 0) {
24659 AERROR_INT("xmlSchemaVCheckCVCSimpleType",xmlSchemaInternalErr(actxt, "xmlSchemaVCheckCVCSimpleType", "validating an item of list simple type"
);
24660 "validating an item of list simple type")xmlSchemaInternalErr(actxt, "xmlSchemaVCheckCVCSimpleType", "validating an item of list simple type"
);
;
24661 goto internal_error;
24662 }
24663 ret = XML_SCHEMAV_CVC_DATATYPE_VALID_1_2_2;
24664 break;
24665 }
24666 cur = end;
24667 } while (*cur != 0);
24668 FREE_AND_NULL(tmpValue)if ((tmpValue) != ((void*)0)) { xmlFree((xmlChar *) (tmpValue
)); tmpValue = ((void*)0); }
;
24669 if ((ret == 0) && (type->flags & XML_SCHEMAS_TYPE_HAS_FACETS1 << 27)) {
24670 /*
24671 * Apply facets (pattern, enumeration).
24672 */
24673 ret = xmlSchemaValidateFacets(actxt, node, type,
24674 XML_SCHEMAS_UNKNOWN, value, val,
24675 len, fireErrors);
24676 if (ret != 0) {
24677 if (ret < 0) {
24678 AERROR_INT("xmlSchemaVCheckCVCSimpleType",xmlSchemaInternalErr(actxt, "xmlSchemaVCheckCVCSimpleType", "validating facets of list simple type"
);
24679 "validating facets of list simple type")xmlSchemaInternalErr(actxt, "xmlSchemaVCheckCVCSimpleType", "validating facets of list simple type"
);
;
24680 goto internal_error;
24681 }
24682 ret = XML_SCHEMAV_CVC_DATATYPE_VALID_1_2_2;
24683 }
24684 }
24685 if (fireErrors && (ret > 0)) {
24686 /*
24687 * Report the normalized value.
24688 */
24689 normalize = 1;
24690 NORMALIZE(type)if ((! isNormalized) && (normalize || (type->flags
& 1 << 28))) { normValue = xmlSchemaNormalizeValue
(type, value); if (normValue != ((void*)0)) value = normValue
; isNormalized = 1; }
;
24691 xmlSchemaSimpleTypeErr(actxt, ret, node, value, type, 1);
24692 }
24693 } else if (WXS_IS_UNION(type)(type->flags & 1 << 7)) {
24694 xmlSchemaTypeLinkPtr memberLink;
24695 /*
24696 * TODO: For all datatypes `derived` by `union` whiteSpace does
24697 * not apply directly; however, the normalization behavior of `union`
24698 * types is controlled by the value of whiteSpace on that one of the
24699 * `memberTypes` against which the `union` is successfully validated.
24700 *
24701 * This means that the value is normalized by the first validating
24702 * member type, then the facets of the union type are applied. This
24703 * needs changing of the value!
24704 */
24705
24706 /*
24707 * 1.2.3 if {variety} is `union` then the string must `match` a
24708 * literal in the `lexical space` of at least one member of
24709 * {member type definitions}
24710 */
24711 memberLink = xmlSchemaGetUnionSimpleTypeMemberTypes(type);
24712 if (memberLink == NULL((void*)0)) {
24713 AERROR_INT("xmlSchemaVCheckCVCSimpleType",xmlSchemaInternalErr(actxt, "xmlSchemaVCheckCVCSimpleType", "union simple type has no member types"
);
24714 "union simple type has no member types")xmlSchemaInternalErr(actxt, "xmlSchemaVCheckCVCSimpleType", "union simple type has no member types"
);
;
24715 goto internal_error;
24716 }
24717 /*
24718 * Always normalize union type values, since we currently
24719 * cannot store the whitespace information with the value
24720 * itself; otherwise a later value-comparison would be
24721 * not possible.
24722 */
24723 while (memberLink != NULL((void*)0)) {
24724 if (valNeeded)
24725 ret = xmlSchemaVCheckCVCSimpleType(actxt, node,
24726 memberLink->type, value, &val, 0, 1, 0);
24727 else
24728 ret = xmlSchemaVCheckCVCSimpleType(actxt, node,
24729 memberLink->type, value, NULL((void*)0), 0, 1, 0);
24730 if (ret <= 0)
24731 break;
24732 memberLink = memberLink->next;
24733 }
24734 if (ret != 0) {
24735 if (ret < 0) {
24736 AERROR_INT("xmlSchemaVCheckCVCSimpleType",xmlSchemaInternalErr(actxt, "xmlSchemaVCheckCVCSimpleType", "validating members of union simple type"
);
24737 "validating members of union simple type")xmlSchemaInternalErr(actxt, "xmlSchemaVCheckCVCSimpleType", "validating members of union simple type"
);
;
24738 goto internal_error;
24739 }
24740 ret = XML_SCHEMAV_CVC_DATATYPE_VALID_1_2_3;
24741 }
24742 /*
24743 * Apply facets (pattern, enumeration).
24744 */
24745 if ((ret == 0) && (type->flags & XML_SCHEMAS_TYPE_HAS_FACETS1 << 27)) {
24746 /*
24747 * The normalization behavior of `union` types is controlled by
24748 * the value of whiteSpace on that one of the `memberTypes`
24749 * against which the `union` is successfully validated.
24750 */
24751 NORMALIZE(memberLink->type)if ((! isNormalized) && (normalize || (type->flags
& 1 << 28))) { normValue = xmlSchemaNormalizeValue
(memberLink->type, value); if (normValue != ((void*)0)) value
= normValue; isNormalized = 1; }
;
24752 ret = xmlSchemaValidateFacets(actxt, node, type,
24753 XML_SCHEMAS_UNKNOWN, value, val,
24754 0, fireErrors);
24755 if (ret != 0) {
24756 if (ret < 0) {
24757 AERROR_INT("xmlSchemaVCheckCVCSimpleType",xmlSchemaInternalErr(actxt, "xmlSchemaVCheckCVCSimpleType", "validating facets of union simple type"
);
24758 "validating facets of union simple type")xmlSchemaInternalErr(actxt, "xmlSchemaVCheckCVCSimpleType", "validating facets of union simple type"
);
;
24759 goto internal_error;
24760 }
24761 ret = XML_SCHEMAV_CVC_DATATYPE_VALID_1_2_3;
24762 }
24763 }
24764 if (fireErrors && (ret > 0))
24765 xmlSchemaSimpleTypeErr(actxt, ret, node, value, type, 1);
24766 }
24767
24768 if (normValue != NULL((void*)0))
24769 xmlFree(normValue);
24770 if (ret == 0) {
24771 if (retVal != NULL((void*)0))
24772 *retVal = val;
24773 else if (val != NULL((void*)0))
24774 xmlSchemaFreeValue(val);
24775 } else if (val != NULL((void*)0))
24776 xmlSchemaFreeValue(val);
24777 return (ret);
24778internal_error:
24779 if (normValue != NULL((void*)0))
24780 xmlFree(normValue);
24781 if (val != NULL((void*)0))
24782 xmlSchemaFreeValue(val);
24783 return (-1);
24784}
24785
24786static int
24787xmlSchemaVExpandQName(xmlSchemaValidCtxtPtr vctxt,
24788 const xmlChar *value,
24789 const xmlChar **nsName,
24790 const xmlChar **localName)
24791{
24792 int ret = 0;
24793
24794 if ((nsName == NULL((void*)0)) || (localName == NULL((void*)0)))
24795 return (-1);
24796 *nsName = NULL((void*)0);
24797 *localName = NULL((void*)0);
24798
24799 ret = xmlValidateQName(value, 1);
24800 if (ret == -1)
24801 return (-1);
24802 if (ret > 0) {
24803 xmlSchemaSimpleTypeErr(ACTXT_CAST(xmlSchemaAbstractCtxtPtr) vctxt,
24804 XML_SCHEMAV_CVC_DATATYPE_VALID_1_2_1, NULL((void*)0),
24805 value, xmlSchemaGetBuiltInType(XML_SCHEMAS_QNAME), 1);
24806 return (1);
24807 }
24808 {
24809 xmlChar *local = NULL((void*)0);
24810 xmlChar *prefix;
24811
24812 /*
24813 * NOTE: xmlSplitQName2 will return a duplicated
24814 * string.
24815 */
24816 local = xmlSplitQName2(value, &prefix);
24817 if (local == NULL((void*)0))
24818 *localName = xmlDictLookup(vctxt->dict, value, -1);
24819 else {
24820 *localName = xmlDictLookup(vctxt->dict, local, -1);
24821 xmlFree(local);
24822 }
24823
24824 *nsName = xmlSchemaLookupNamespace(vctxt, prefix);
24825
24826 if (prefix != NULL((void*)0)) {
24827 xmlFree(prefix);
24828 /*
24829 * A namespace must be found if the prefix is NOT NULL.
24830 */
24831 if (*nsName == NULL((void*)0)) {
24832 xmlSchemaCustomErr(ACTXT_CAST(xmlSchemaAbstractCtxtPtr) vctxt,
24833 XML_SCHEMAV_CVC_DATATYPE_VALID_1_2_1, NULL((void*)0),
24834 WXS_BASIC_CAST(xmlSchemaBasicItemPtr) xmlSchemaGetBuiltInType(XML_SCHEMAS_QNAME),
24835 "The QName value '%s' has no "
24836 "corresponding namespace declaration in scope",
24837 value, NULL((void*)0));
24838 return (2);
24839 }
24840 }
24841 }
24842 return (0);
24843}
24844
24845static int
24846xmlSchemaProcessXSIType(xmlSchemaValidCtxtPtr vctxt,
24847 xmlSchemaAttrInfoPtr iattr,
24848 xmlSchemaTypePtr *localType,
24849 xmlSchemaElementPtr elemDecl)
24850{
24851 int ret = 0;
24852 /*
24853 * cvc-elt (3.3.4) : (4)
24854 * AND
24855 * Schema-Validity Assessment (Element) (cvc-assess-elt)
24856 * (1.2.1.2.1) - (1.2.1.2.4)
24857 * Handle 'xsi:type'.
24858 */
24859 if (localType == NULL((void*)0))
24860 return (-1);
24861 *localType = NULL((void*)0);
24862 if (iattr == NULL((void*)0))
24863 return (0);
24864 else {
24865 const xmlChar *nsName = NULL((void*)0), *local = NULL((void*)0);
24866 /*
24867 * TODO: We should report a *warning* that the type was overridden
24868 * by the instance.
24869 */
24870 ACTIVATE_ATTRIBUTE(iattr)vctxt->inode = (xmlSchemaNodeInfoPtr) iattr;;
24871 /*
24872 * (cvc-elt) (3.3.4) : (4.1)
24873 * (cvc-assess-elt) (1.2.1.2.2)
24874 */
24875 ret = xmlSchemaVExpandQName(vctxt, iattr->value,
24876 &nsName, &local);
24877 if (ret != 0) {
24878 if (ret < 0) {
24879 VERROR_INT("xmlSchemaValidateElementByDeclaration",xmlSchemaInternalErr((xmlSchemaAbstractCtxtPtr) vctxt, "xmlSchemaValidateElementByDeclaration"
, "calling xmlSchemaQNameExpand() to validate the " "attribute 'xsi:type'"
);
24880 "calling xmlSchemaQNameExpand() to validate the "xmlSchemaInternalErr((xmlSchemaAbstractCtxtPtr) vctxt, "xmlSchemaValidateElementByDeclaration"
, "calling xmlSchemaQNameExpand() to validate the " "attribute 'xsi:type'"
);
24881 "attribute 'xsi:type'")xmlSchemaInternalErr((xmlSchemaAbstractCtxtPtr) vctxt, "xmlSchemaValidateElementByDeclaration"
, "calling xmlSchemaQNameExpand() to validate the " "attribute 'xsi:type'"
);
;
24882 goto internal_error;
24883 }
24884 goto exit;
24885 }
24886 /*
24887 * (cvc-elt) (3.3.4) : (4.2)
24888 * (cvc-assess-elt) (1.2.1.2.3)
24889 */
24890 *localType = xmlSchemaGetType(vctxt->schema, local, nsName);
24891 if (*localType == NULL((void*)0)) {
24892 xmlChar *str = NULL((void*)0);
24893
24894 xmlSchemaCustomErr(ACTXT_CAST(xmlSchemaAbstractCtxtPtr) vctxt,
24895 XML_SCHEMAV_CVC_ELT_4_2, NULL((void*)0),
24896 WXS_BASIC_CAST(xmlSchemaBasicItemPtr) xmlSchemaGetBuiltInType(XML_SCHEMAS_QNAME),
24897 "The QName value '%s' of the xsi:type attribute does not "
24898 "resolve to a type definition",
24899 xmlSchemaFormatQName(&str, nsName, local), NULL((void*)0));
24900 FREE_AND_NULL(str)if ((str) != ((void*)0)) { xmlFree((xmlChar *) (str)); str = (
(void*)0); }
;
24901 ret = vctxt->err;
24902 goto exit;
24903 }
24904 if (elemDecl != NULL((void*)0)) {
24905 int set = 0;
24906
24907 /*
24908 * SPEC cvc-elt (3.3.4) : (4.3) (Type Derivation OK)
24909 * "The `local type definition` must be validly
24910 * derived from the {type definition} given the union of
24911 * the {disallowed substitutions} and the {type definition}'s
24912 * {prohibited substitutions}, as defined in
24913 * Type Derivation OK (Complex) ($3.4.6)
24914 * (if it is a complex type definition),
24915 * or given {disallowed substitutions} as defined in Type
24916 * Derivation OK (Simple) ($3.14.6) (if it is a simple type
24917 * definition)."
24918 *
24919 * {disallowed substitutions}: the "block" on the element decl.
24920 * {prohibited substitutions}: the "block" on the type def.
24921 */
24922 /*
24923 * OPTIMIZE TODO: We could map types already evaluated
24924 * to be validly derived from other types to avoid checking
24925 * this over and over for the same types.
24926 */
24927 if ((elemDecl->flags & XML_SCHEMAS_ELEM_BLOCK_EXTENSION1 << 11) ||
24928 (elemDecl->subtypes->flags &
24929 XML_SCHEMAS_TYPE_BLOCK_EXTENSION1 << 18))
24930 set |= SUBSET_EXTENSION1<<1;
24931
24932 if ((elemDecl->flags & XML_SCHEMAS_ELEM_BLOCK_RESTRICTION1 << 12) ||
24933 (elemDecl->subtypes->flags &
24934 XML_SCHEMAS_TYPE_BLOCK_RESTRICTION1 << 19))
24935 set |= SUBSET_RESTRICTION1<<0;
24936
24937 /*
24938 * REMOVED and CHANGED since this produced a parser context
24939 * which adds to the string dict of the schema. So this would
24940 * change the schema and we don't want this. We don't need
24941 * the parser context anymore.
24942 *
24943 * if ((vctxt->pctxt == NULL) &&
24944 * (xmlSchemaCreatePCtxtOnVCtxt(vctxt) == -1))
24945 * return (-1);
24946 */
24947
24948 if (xmlSchemaCheckCOSDerivedOK(ACTXT_CAST(xmlSchemaAbstractCtxtPtr) vctxt, *localType,
24949 elemDecl->subtypes, set) != 0) {
24950 xmlChar *str = NULL((void*)0);
24951
24952 xmlSchemaCustomErr(ACTXT_CAST(xmlSchemaAbstractCtxtPtr) vctxt,
24953 XML_SCHEMAV_CVC_ELT_4_3, NULL((void*)0), NULL((void*)0),
24954 "The type definition '%s', specified by xsi:type, is "
24955 "blocked or not validly derived from the type definition "
24956 "of the element declaration",
24957 xmlSchemaFormatQName(&str,
24958 (*localType)->targetNamespace,
24959 (*localType)->name),
24960 NULL((void*)0));
24961 FREE_AND_NULL(str)if ((str) != ((void*)0)) { xmlFree((xmlChar *) (str)); str = (
(void*)0); }
;
24962 ret = vctxt->err;
24963 *localType = NULL((void*)0);
24964 }
24965 }
24966 }
24967exit:
24968 ACTIVATE_ELEMvctxt->inode = vctxt->elemInfos[vctxt->depth];;
24969 return (ret);
24970internal_error:
24971 ACTIVATE_ELEMvctxt->inode = vctxt->elemInfos[vctxt->depth];;
24972 return (-1);
24973}
24974
24975static int
24976xmlSchemaValidateElemDecl(xmlSchemaValidCtxtPtr vctxt)
24977{
24978 xmlSchemaElementPtr elemDecl = vctxt->inode->decl;
24979 xmlSchemaTypePtr actualType;
24980
24981 /*
24982 * cvc-elt (3.3.4) : 1
24983 */
24984 if (elemDecl == NULL((void*)0)) {
24985 VERROR(XML_SCHEMAV_CVC_ELT_1, NULL,xmlSchemaCustomErr((xmlSchemaAbstractCtxtPtr) vctxt, XML_SCHEMAV_CVC_ELT_1
, ((void*)0), ((void*)0), "No matching declaration available"
, ((void*)0), ((void*)0));
24986 "No matching declaration available")xmlSchemaCustomErr((xmlSchemaAbstractCtxtPtr) vctxt, XML_SCHEMAV_CVC_ELT_1
, ((void*)0), ((void*)0), "No matching declaration available"
, ((void*)0), ((void*)0));
;
24987 return (vctxt->err);
24988 }
24989 actualType = WXS_ELEM_TYPEDEF(elemDecl)(elemDecl)->subtypes;
24990 /*
24991 * cvc-elt (3.3.4) : 2
24992 */
24993 if (elemDecl->flags & XML_SCHEMAS_ELEM_ABSTRACT1 << 4) {
24994 VERROR(XML_SCHEMAV_CVC_ELT_2, NULL,xmlSchemaCustomErr((xmlSchemaAbstractCtxtPtr) vctxt, XML_SCHEMAV_CVC_ELT_2
, ((void*)0), ((void*)0), "The element declaration is abstract"
, ((void*)0), ((void*)0));
24995 "The element declaration is abstract")xmlSchemaCustomErr((xmlSchemaAbstractCtxtPtr) vctxt, XML_SCHEMAV_CVC_ELT_2
, ((void*)0), ((void*)0), "The element declaration is abstract"
, ((void*)0), ((void*)0));
;
24996 return (vctxt->err);
24997 }
24998 if (actualType == NULL((void*)0)) {
24999 VERROR(XML_SCHEMAV_CVC_TYPE_1, NULL,xmlSchemaCustomErr((xmlSchemaAbstractCtxtPtr) vctxt, XML_SCHEMAV_CVC_TYPE_1
, ((void*)0), ((void*)0), "The type definition is absent", ((
void*)0), ((void*)0));
25000 "The type definition is absent")xmlSchemaCustomErr((xmlSchemaAbstractCtxtPtr) vctxt, XML_SCHEMAV_CVC_TYPE_1
, ((void*)0), ((void*)0), "The type definition is absent", ((
void*)0), ((void*)0));
;
25001 return (XML_SCHEMAV_CVC_TYPE_1);
25002 }
25003 if (vctxt->nbAttrInfos != 0) {
25004 int ret;
25005 xmlSchemaAttrInfoPtr iattr;
25006 /*
25007 * cvc-elt (3.3.4) : 3
25008 * Handle 'xsi:nil'.
25009 */
25010 iattr = xmlSchemaGetMetaAttrInfo(vctxt,
25011 XML_SCHEMA_ATTR_INFO_META_XSI_NIL2);
25012 if (iattr) {
25013 ACTIVATE_ATTRIBUTE(iattr)vctxt->inode = (xmlSchemaNodeInfoPtr) iattr;;
25014 /*
25015 * Validate the value.
25016 */
25017 ret = xmlSchemaVCheckCVCSimpleType(
25018 ACTXT_CAST(xmlSchemaAbstractCtxtPtr) vctxt, NULL((void*)0),
25019 xmlSchemaGetBuiltInType(XML_SCHEMAS_BOOLEAN),
25020 iattr->value, &(iattr->val), 1, 0, 0);
25021 ACTIVATE_ELEMvctxt->inode = vctxt->elemInfos[vctxt->depth];;
25022 if (ret < 0) {
25023 VERROR_INT("xmlSchemaValidateElemDecl",xmlSchemaInternalErr((xmlSchemaAbstractCtxtPtr) vctxt, "xmlSchemaValidateElemDecl"
, "calling xmlSchemaVCheckCVCSimpleType() to " "validate the attribute 'xsi:nil'"
);
25024 "calling xmlSchemaVCheckCVCSimpleType() to "xmlSchemaInternalErr((xmlSchemaAbstractCtxtPtr) vctxt, "xmlSchemaValidateElemDecl"
, "calling xmlSchemaVCheckCVCSimpleType() to " "validate the attribute 'xsi:nil'"
);
25025 "validate the attribute 'xsi:nil'")xmlSchemaInternalErr((xmlSchemaAbstractCtxtPtr) vctxt, "xmlSchemaValidateElemDecl"
, "calling xmlSchemaVCheckCVCSimpleType() to " "validate the attribute 'xsi:nil'"
);
;
25026 return (-1);
25027 }
25028 if (ret == 0) {
25029 if ((elemDecl->flags & XML_SCHEMAS_ELEM_NILLABLE1 << 0) == 0) {
25030 /*
25031 * cvc-elt (3.3.4) : 3.1
25032 */
25033 VERROR(XML_SCHEMAV_CVC_ELT_3_1, NULL,xmlSchemaCustomErr((xmlSchemaAbstractCtxtPtr) vctxt, XML_SCHEMAV_CVC_ELT_3_1
, ((void*)0), ((void*)0), "The element is not 'nillable'", ((
void*)0), ((void*)0));
25034 "The element is not 'nillable'")xmlSchemaCustomErr((xmlSchemaAbstractCtxtPtr) vctxt, XML_SCHEMAV_CVC_ELT_3_1
, ((void*)0), ((void*)0), "The element is not 'nillable'", ((
void*)0), ((void*)0));
;
25035 /* Does not return an error on purpose. */
25036 } else {
25037 if (xmlSchemaValueGetAsBoolean(iattr->val)) {
25038 /*
25039 * cvc-elt (3.3.4) : 3.2.2
25040 */
25041 if ((elemDecl->flags & XML_SCHEMAS_ELEM_FIXED1 << 3) &&
25042 (elemDecl->value != NULL((void*)0))) {
25043 VERROR(XML_SCHEMAV_CVC_ELT_3_2_2, NULL,xmlSchemaCustomErr((xmlSchemaAbstractCtxtPtr) vctxt, XML_SCHEMAV_CVC_ELT_3_2_2
, ((void*)0), ((void*)0), "The element cannot be 'nilled' because "
"there is a fixed value constraint defined " "for it", ((void
*)0), ((void*)0));
25044 "The element cannot be 'nilled' because "xmlSchemaCustomErr((xmlSchemaAbstractCtxtPtr) vctxt, XML_SCHEMAV_CVC_ELT_3_2_2
, ((void*)0), ((void*)0), "The element cannot be 'nilled' because "
"there is a fixed value constraint defined " "for it", ((void
*)0), ((void*)0));
25045 "there is a fixed value constraint defined "xmlSchemaCustomErr((xmlSchemaAbstractCtxtPtr) vctxt, XML_SCHEMAV_CVC_ELT_3_2_2
, ((void*)0), ((void*)0), "The element cannot be 'nilled' because "
"there is a fixed value constraint defined " "for it", ((void
*)0), ((void*)0));
25046 "for it")xmlSchemaCustomErr((xmlSchemaAbstractCtxtPtr) vctxt, XML_SCHEMAV_CVC_ELT_3_2_2
, ((void*)0), ((void*)0), "The element cannot be 'nilled' because "
"there is a fixed value constraint defined " "for it", ((void
*)0), ((void*)0));
;
25047 /* Does not return an error on purpose. */
25048 } else
25049 vctxt->inode->flags |=
25050 XML_SCHEMA_ELEM_INFO_NILLED1<<2;
25051 }
25052 }
25053 }
25054 }
25055 /*
25056 * cvc-elt (3.3.4) : 4
25057 * Handle 'xsi:type'.
25058 */
25059 iattr = xmlSchemaGetMetaAttrInfo(vctxt,
25060 XML_SCHEMA_ATTR_INFO_META_XSI_TYPE1);
25061 if (iattr) {
25062 xmlSchemaTypePtr localType = NULL((void*)0);
25063
25064 ret = xmlSchemaProcessXSIType(vctxt, iattr, &localType,
25065 elemDecl);
25066 if (ret != 0) {
25067 if (ret == -1) {
25068 VERROR_INT("xmlSchemaValidateElemDecl",xmlSchemaInternalErr((xmlSchemaAbstractCtxtPtr) vctxt, "xmlSchemaValidateElemDecl"
, "calling xmlSchemaProcessXSIType() to " "process the attribute 'xsi:type'"
);
25069 "calling xmlSchemaProcessXSIType() to "xmlSchemaInternalErr((xmlSchemaAbstractCtxtPtr) vctxt, "xmlSchemaValidateElemDecl"
, "calling xmlSchemaProcessXSIType() to " "process the attribute 'xsi:type'"
);
25070 "process the attribute 'xsi:type'")xmlSchemaInternalErr((xmlSchemaAbstractCtxtPtr) vctxt, "xmlSchemaValidateElemDecl"
, "calling xmlSchemaProcessXSIType() to " "process the attribute 'xsi:type'"
);
;
25071 return (-1);
25072 }
25073 /* Does not return an error on purpose. */
25074 }
25075 if (localType != NULL((void*)0)) {
25076 vctxt->inode->flags |= XML_SCHEMA_ELEM_INFO_LOCAL_TYPE1<<3;
25077 actualType = localType;
25078 }
25079 }
25080 }
25081 /*
25082 * IDC: Register identity-constraint XPath matchers.
25083 */
25084 if ((elemDecl->idcs != NULL((void*)0)) &&
25085 (xmlSchemaIDCRegisterMatchers(vctxt, elemDecl) == -1))
25086 return (-1);
25087 /*
25088 * No actual type definition.
25089 */
25090 if (actualType == NULL((void*)0)) {
25091 VERROR(XML_SCHEMAV_CVC_TYPE_1, NULL,xmlSchemaCustomErr((xmlSchemaAbstractCtxtPtr) vctxt, XML_SCHEMAV_CVC_TYPE_1
, ((void*)0), ((void*)0), "The type definition is absent", ((
void*)0), ((void*)0));
25092 "The type definition is absent")xmlSchemaCustomErr((xmlSchemaAbstractCtxtPtr) vctxt, XML_SCHEMAV_CVC_TYPE_1
, ((void*)0), ((void*)0), "The type definition is absent", ((
void*)0), ((void*)0));
;
25093 return (XML_SCHEMAV_CVC_TYPE_1);
25094 }
25095 /*
25096 * Remember the actual type definition.
25097 */
25098 vctxt->inode->typeDef = actualType;
25099
25100 return (0);
25101}
25102
25103static int
25104xmlSchemaVAttributesSimple(xmlSchemaValidCtxtPtr vctxt)
25105{
25106 xmlSchemaAttrInfoPtr iattr;
25107 int ret = 0, i;
25108
25109 /*
25110 * SPEC cvc-type (3.1.1)
25111 * "The attributes of must be empty, excepting those whose namespace
25112 * name is identical to http://www.w3.org/2001/XMLSchema-instance and
25113 * whose local name is one of type, nil, schemaLocation or
25114 * noNamespaceSchemaLocation."
25115 */
25116 if (vctxt->nbAttrInfos == 0)
25117 return (0);
25118 for (i = 0; i < vctxt->nbAttrInfos; i++) {
25119 iattr = vctxt->attrInfos[i];
25120 if (! iattr->metaType) {
25121 ACTIVATE_ATTRIBUTE(iattr)vctxt->inode = (xmlSchemaNodeInfoPtr) iattr;
25122 xmlSchemaIllegalAttrErr(ACTXT_CAST(xmlSchemaAbstractCtxtPtr) vctxt,
25123 XML_SCHEMAV_CVC_TYPE_3_1_1, iattr, NULL((void*)0));
25124 ret = XML_SCHEMAV_CVC_TYPE_3_1_1;
25125 }
25126 }
25127 ACTIVATE_ELEMvctxt->inode = vctxt->elemInfos[vctxt->depth];
25128 return (ret);
25129}
25130
25131/*
25132* Cleanup currently used attribute infos.
25133*/
25134static void
25135xmlSchemaClearAttrInfos(xmlSchemaValidCtxtPtr vctxt)
25136{
25137 int i;
25138 xmlSchemaAttrInfoPtr attr;
25139
25140 if (vctxt->nbAttrInfos == 0)
25141 return;
25142 for (i = 0; i < vctxt->nbAttrInfos; i++) {
25143 attr = vctxt->attrInfos[i];
25144 if (attr->flags & XML_SCHEMA_NODE_INFO_FLAG_OWNED_NAMES1<<0) {
25145 if (attr->localName != NULL((void*)0))
25146 xmlFree((xmlChar *) attr->localName);
25147 if (attr->nsName != NULL((void*)0))
25148 xmlFree((xmlChar *) attr->nsName);
25149 }
25150 if (attr->flags & XML_SCHEMA_NODE_INFO_FLAG_OWNED_VALUES1<<1) {
25151 if (attr->value != NULL((void*)0))
25152 xmlFree((xmlChar *) attr->value);
25153 }
25154 if (attr->val != NULL((void*)0)) {
25155 xmlSchemaFreeValue(attr->val);
25156 attr->val = NULL((void*)0);
25157 }
25158 memset(attr, 0, sizeof(xmlSchemaAttrInfo));
25159 }
25160 vctxt->nbAttrInfos = 0;
25161}
25162
25163/*
25164* 3.4.4 Complex Type Definition Validation Rules
25165* Element Locally Valid (Complex Type) (cvc-complex-type)
25166* 3.2.4 Attribute Declaration Validation Rules
25167* Validation Rule: Attribute Locally Valid (cvc-attribute)
25168* Attribute Locally Valid (Use) (cvc-au)
25169*
25170* Only "assessed" attribute information items will be visible to
25171* IDCs. I.e. not "lax" (without declaration) and "skip" wild attributes.
25172*/
25173static int
25174xmlSchemaVAttributesComplex(xmlSchemaValidCtxtPtr vctxt)
25175{
25176 xmlSchemaTypePtr type = vctxt->inode->typeDef;
25177 xmlSchemaItemListPtr attrUseList;
25178 xmlSchemaAttributeUsePtr attrUse = NULL((void*)0);
25179 xmlSchemaAttributePtr attrDecl = NULL((void*)0);
25180 xmlSchemaAttrInfoPtr iattr, tmpiattr;
25181 int i, j, found, nbAttrs, nbUses;
25182 int xpathRes = 0, res, wildIDs = 0, fixed;
25183 xmlNodePtr defAttrOwnerElem = NULL((void*)0);
25184
25185 /*
25186 * SPEC (cvc-attribute)
25187 * (1) "The declaration must not be `absent` (see Missing
25188 * Sub-components ($5.3) for how this can fail to be
25189 * the case)."
25190 * (2) "Its {type definition} must not be absent."
25191 *
25192 * NOTE (1) + (2): This is not handled here, since we currently do not
25193 * allow validation against schemas which have missing sub-components.
25194 *
25195 * SPEC (cvc-complex-type)
25196 * (3) "For each attribute information item in the element information
25197 * item's [attributes] excepting those whose [namespace name] is
25198 * identical to http://www.w3.org/2001/XMLSchema-instance and whose
25199 * [local name] is one of type, nil, schemaLocation or
25200 * noNamespaceSchemaLocation, the appropriate case among the following
25201 * must be true:
25202 *
25203 */
25204 attrUseList = (xmlSchemaItemListPtr) type->attrUses;
25205 /*
25206 * @nbAttrs is the number of attributes present in the instance.
25207 */
25208 nbAttrs = vctxt->nbAttrInfos;
25209 if (attrUseList != NULL((void*)0))
25210 nbUses = attrUseList->nbItems;
25211 else
25212 nbUses = 0;
25213 for (i = 0; i < nbUses; i++) {
25214 found = 0;
25215 attrUse = attrUseList->items[i];
25216 attrDecl = WXS_ATTRUSE_DECL(attrUse)((xmlSchemaAttributeUsePtr) (attrUse))->attrDecl;
25217 for (j = 0; j < nbAttrs; j++) {
25218 iattr = vctxt->attrInfos[j];
25219 /*
25220 * SPEC (cvc-complex-type) (3)
25221 * Skip meta attributes.
25222 */
25223 if (iattr->metaType)
25224 continue;
25225 if (iattr->localName[0] != attrDecl->name[0])
25226 continue;
25227 if (!xmlStrEqual(iattr->localName, attrDecl->name))
25228 continue;
25229 if (!xmlStrEqual(iattr->nsName, attrDecl->targetNamespace))
25230 continue;
25231 found = 1;
25232 /*
25233 * SPEC (cvc-complex-type)
25234 * (3.1) "If there is among the {attribute uses} an attribute
25235 * use with an {attribute declaration} whose {name} matches
25236 * the attribute information item's [local name] and whose
25237 * {target namespace} is identical to the attribute information
25238 * item's [namespace name] (where an `absent` {target namespace}
25239 * is taken to be identical to a [namespace name] with no value),
25240 * then the attribute information must be `valid` with respect
25241 * to that attribute use as per Attribute Locally Valid (Use)
25242 * ($3.5.4). In this case the {attribute declaration} of that
25243 * attribute use is the `context-determined declaration` for the
25244 * attribute information item with respect to Schema-Validity
25245 * Assessment (Attribute) ($3.2.4) and
25246 * Assessment Outcome (Attribute) ($3.2.5).
25247 */
25248 iattr->state = XML_SCHEMAS_ATTR_ASSESSED2;
25249 iattr->use = attrUse;
25250 /*
25251 * Context-determined declaration.
25252 */
25253 iattr->decl = attrDecl;
25254 iattr->typeDef = attrDecl->subtypes;
25255 break;
25256 }
25257
25258 if (found)
25259 continue;
25260
25261 if (attrUse->occurs == XML_SCHEMAS_ATTR_USE_REQUIRED1) {
25262 /*
25263 * Handle non-existent, required attributes.
25264 *
25265 * SPEC (cvc-complex-type)
25266 * (4) "The {attribute declaration} of each attribute use in
25267 * the {attribute uses} whose {required} is true matches one
25268 * of the attribute information items in the element information
25269 * item's [attributes] as per clause 3.1 above."
25270 */
25271 tmpiattr = xmlSchemaGetFreshAttrInfo(vctxt);
25272 if (tmpiattr == NULL((void*)0)) {
25273 VERROR_INT(xmlSchemaInternalErr((xmlSchemaAbstractCtxtPtr) vctxt, "xmlSchemaVAttributesComplex"
, "calling xmlSchemaGetFreshAttrInfo()");
25274 "xmlSchemaVAttributesComplex",xmlSchemaInternalErr((xmlSchemaAbstractCtxtPtr) vctxt, "xmlSchemaVAttributesComplex"
, "calling xmlSchemaGetFreshAttrInfo()");
25275 "calling xmlSchemaGetFreshAttrInfo()")xmlSchemaInternalErr((xmlSchemaAbstractCtxtPtr) vctxt, "xmlSchemaVAttributesComplex"
, "calling xmlSchemaGetFreshAttrInfo()");
;
25276 return (-1);
25277 }
25278 tmpiattr->state = XML_SCHEMAS_ATTR_ERR_MISSING4;
25279 tmpiattr->use = attrUse;
25280 tmpiattr->decl = attrDecl;
25281 } else if ((attrUse->occurs == XML_SCHEMAS_ATTR_USE_OPTIONAL2) &&
25282 ((attrUse->defValue != NULL((void*)0)) ||
25283 (attrDecl->defValue != NULL((void*)0)))) {
25284 /*
25285 * Handle non-existent, optional, default/fixed attributes.
25286 */
25287 tmpiattr = xmlSchemaGetFreshAttrInfo(vctxt);
25288 if (tmpiattr == NULL((void*)0)) {
25289 VERROR_INT(xmlSchemaInternalErr((xmlSchemaAbstractCtxtPtr) vctxt, "xmlSchemaVAttributesComplex"
, "calling xmlSchemaGetFreshAttrInfo()");
25290 "xmlSchemaVAttributesComplex",xmlSchemaInternalErr((xmlSchemaAbstractCtxtPtr) vctxt, "xmlSchemaVAttributesComplex"
, "calling xmlSchemaGetFreshAttrInfo()");
25291 "calling xmlSchemaGetFreshAttrInfo()")xmlSchemaInternalErr((xmlSchemaAbstractCtxtPtr) vctxt, "xmlSchemaVAttributesComplex"
, "calling xmlSchemaGetFreshAttrInfo()");
;
25292 return (-1);
25293 }
25294 tmpiattr->state = XML_SCHEMAS_ATTR_DEFAULT8;
25295 tmpiattr->use = attrUse;
25296 tmpiattr->decl = attrDecl;
25297 tmpiattr->typeDef = attrDecl->subtypes;
25298 tmpiattr->localName = attrDecl->name;
25299 tmpiattr->nsName = attrDecl->targetNamespace;
25300 }
25301 }
25302
25303 if (vctxt->nbAttrInfos == 0)
25304 return (0);
25305 /*
25306 * Validate against the wildcard.
25307 */
25308 if (type->attributeWildcard != NULL((void*)0)) {
25309 /*
25310 * SPEC (cvc-complex-type)
25311 * (3.2.1) "There must be an {attribute wildcard}."
25312 */
25313 for (i = 0; i < nbAttrs; i++) {
25314 iattr = vctxt->attrInfos[i];
25315 /*
25316 * SPEC (cvc-complex-type) (3)
25317 * Skip meta attributes.
25318 */
25319 if (iattr->state != XML_SCHEMAS_ATTR_UNKNOWN1)
25320 continue;
25321 /*
25322 * SPEC (cvc-complex-type)
25323 * (3.2.2) "The attribute information item must be `valid` with
25324 * respect to it as defined in Item Valid (Wildcard) ($3.10.4)."
25325 *
25326 * SPEC Item Valid (Wildcard) (cvc-wildcard)
25327 * "... its [namespace name] must be `valid` with respect to
25328 * the wildcard constraint, as defined in Wildcard allows
25329 * Namespace Name ($3.10.4)."
25330 */
25331 if (xmlSchemaCheckCVCWildcardNamespace(type->attributeWildcard,
25332 iattr->nsName) == 0) {
25333 /*
25334 * Handle processContents.
25335 *
25336 * SPEC (cvc-wildcard):
25337 * processContents | context-determined declaration:
25338 * "strict" "mustFind"
25339 * "lax" "none"
25340 * "skip" "skip"
25341 */
25342 if (type->attributeWildcard->processContents ==
25343 XML_SCHEMAS_ANY_SKIP1) {
25344 /*
25345 * context-determined declaration = "skip"
25346 *
25347 * SPEC PSVI Assessment Outcome (Attribute)
25348 * [validity] = "notKnown"
25349 * [validation attempted] = "none"
25350 */
25351 iattr->state = XML_SCHEMAS_ATTR_WILD_SKIP13;
25352 continue;
25353 }
25354 /*
25355 * Find an attribute declaration.
25356 */
25357 iattr->decl = xmlSchemaGetAttributeDecl(vctxt->schema,
25358 iattr->localName, iattr->nsName);
25359 if (iattr->decl != NULL((void*)0)) {
25360 iattr->state = XML_SCHEMAS_ATTR_ASSESSED2;
25361 /*
25362 * SPEC (cvc-complex-type)
25363 * (5) "Let [Definition:] the wild IDs be the set of
25364 * all attribute information item to which clause 3.2
25365 * applied and whose `validation` resulted in a
25366 * `context-determined declaration` of mustFind or no
25367 * `context-determined declaration` at all, and whose
25368 * [local name] and [namespace name] resolve (as
25369 * defined by QName resolution (Instance) ($3.15.4)) to
25370 * an attribute declaration whose {type definition} is
25371 * or is derived from ID. Then all of the following
25372 * must be true:"
25373 */
25374 iattr->typeDef = WXS_ATTR_TYPEDEF(iattr->decl)(iattr->decl)->subtypes;
25375 if (xmlSchemaIsDerivedFromBuiltInType(
25376 iattr->typeDef, XML_SCHEMAS_ID)) {
25377 /*
25378 * SPEC (5.1) "There must be no more than one
25379 * item in `wild IDs`."
25380 */
25381 if (wildIDs != 0) {
25382 /* VAL TODO */
25383 iattr->state = XML_SCHEMAS_ATTR_ERR_WILD_DUPLICATE_ID15;
25384 TODO(*__xmlGenericError())((*__xmlGenericErrorContext()), "Unimplemented block at %s:%d\n"
, "xmlschemas.c", 25384);
25385 continue;
25386 }
25387 wildIDs++;
25388 /*
25389 * SPEC (cvc-complex-type)
25390 * (5.2) "If `wild IDs` is non-empty, there must not
25391 * be any attribute uses among the {attribute uses}
25392 * whose {attribute declaration}'s {type definition}
25393 * is or is derived from ID."
25394 */
25395 if (attrUseList != NULL((void*)0)) {
25396 for (j = 0; j < attrUseList->nbItems; j++) {
25397 if (xmlSchemaIsDerivedFromBuiltInType(
25398 WXS_ATTRUSE_TYPEDEF(attrUseList->items[j])(((xmlSchemaAttributeUsePtr) ((xmlSchemaAttributeUsePtr) attrUseList
->items[j]))->attrDecl)->subtypes
,
25399 XML_SCHEMAS_ID)) {
25400 /* URGENT VAL TODO: implement */
25401 iattr->state = XML_SCHEMAS_ATTR_ERR_WILD_AND_USE_ID16;
25402 TODO(*__xmlGenericError())((*__xmlGenericErrorContext()), "Unimplemented block at %s:%d\n"
, "xmlschemas.c", 25402);
25403 break;
25404 }
25405 }
25406 }
25407 }
25408 } else if (type->attributeWildcard->processContents ==
25409 XML_SCHEMAS_ANY_LAX2) {
25410 iattr->state = XML_SCHEMAS_ATTR_WILD_LAX_NO_DECL14;
25411 /*
25412 * SPEC PSVI Assessment Outcome (Attribute)
25413 * [validity] = "notKnown"
25414 * [validation attempted] = "none"
25415 */
25416 } else {
25417 iattr->state = XML_SCHEMAS_ATTR_ERR_WILD_STRICT_NO_DECL10;
25418 }
25419 }
25420 }
25421 }
25422
25423 if (vctxt->nbAttrInfos == 0)
25424 return (0);
25425
25426 /*
25427 * Get the owner element; needed for creation of default attributes.
25428 * This fixes bug #341337, reported by David Grohmann.
25429 */
25430 if (vctxt->options & XML_SCHEMA_VAL_VC_I_CREATE) {
25431 xmlSchemaNodeInfoPtr ielem = vctxt->elemInfos[vctxt->depth];
25432 if (ielem && ielem->node && ielem->node->doc)
25433 defAttrOwnerElem = ielem->node;
25434 }
25435 /*
25436 * Validate values, create default attributes, evaluate IDCs.
25437 */
25438 for (i = 0; i < vctxt->nbAttrInfos; i++) {
25439 iattr = vctxt->attrInfos[i];
25440 /*
25441 * VAL TODO: Note that we won't try to resolve IDCs to
25442 * "lax" and "skip" validated attributes. Check what to
25443 * do in this case.
25444 */
25445 if ((iattr->state != XML_SCHEMAS_ATTR_ASSESSED2) &&
25446 (iattr->state != XML_SCHEMAS_ATTR_DEFAULT8))
25447 continue;
25448 /*
25449 * VAL TODO: What to do if the type definition is missing?
25450 */
25451 if (iattr->typeDef == NULL((void*)0)) {
25452 iattr->state = XML_SCHEMAS_ATTR_ERR_NO_TYPE6;
25453 continue;
25454 }
25455
25456 ACTIVATE_ATTRIBUTE(iattr)vctxt->inode = (xmlSchemaNodeInfoPtr) iattr;;
25457 fixed = 0;
25458 xpathRes = 0;
25459
25460 if (vctxt->xpathStates != NULL((void*)0)) {
25461 /*
25462 * Evaluate IDCs.
25463 */
25464 xpathRes = xmlSchemaXPathEvaluate(vctxt,
25465 XML_ATTRIBUTE_NODE);
25466 if (xpathRes == -1) {
25467 VERROR_INT("xmlSchemaVAttributesComplex",xmlSchemaInternalErr((xmlSchemaAbstractCtxtPtr) vctxt, "xmlSchemaVAttributesComplex"
, "calling xmlSchemaXPathEvaluate()");
25468 "calling xmlSchemaXPathEvaluate()")xmlSchemaInternalErr((xmlSchemaAbstractCtxtPtr) vctxt, "xmlSchemaVAttributesComplex"
, "calling xmlSchemaXPathEvaluate()");
;
25469 goto internal_error;
25470 }
25471 }
25472
25473 if (iattr->state == XML_SCHEMAS_ATTR_DEFAULT8) {
25474 /*
25475 * Default/fixed attributes.
25476 * We need the value only if we need to resolve IDCs or
25477 * will create default attributes.
25478 */
25479 if ((xpathRes) || (defAttrOwnerElem)) {
25480 if (iattr->use->defValue != NULL((void*)0)) {
25481 iattr->value = (xmlChar *) iattr->use->defValue;
25482 iattr->val = iattr->use->defVal;
25483 } else {
25484 iattr->value = (xmlChar *) iattr->decl->defValue;
25485 iattr->val = iattr->decl->defVal;
25486 }
25487 /*
25488 * IDCs will consume the precomputed default value,
25489 * so we need to clone it.
25490 */
25491 if (iattr->val == NULL((void*)0)) {
25492 VERROR_INT("xmlSchemaVAttributesComplex",xmlSchemaInternalErr((xmlSchemaAbstractCtxtPtr) vctxt, "xmlSchemaVAttributesComplex"
, "default/fixed value on an attribute use was " "not precomputed"
);
25493 "default/fixed value on an attribute use was "xmlSchemaInternalErr((xmlSchemaAbstractCtxtPtr) vctxt, "xmlSchemaVAttributesComplex"
, "default/fixed value on an attribute use was " "not precomputed"
);
25494 "not precomputed")xmlSchemaInternalErr((xmlSchemaAbstractCtxtPtr) vctxt, "xmlSchemaVAttributesComplex"
, "default/fixed value on an attribute use was " "not precomputed"
);
;
25495 goto internal_error;
25496 }
25497 iattr->val = xmlSchemaCopyValue(iattr->val);
25498 if (iattr->val == NULL((void*)0)) {
25499 VERROR_INT("xmlSchemaVAttributesComplex",xmlSchemaInternalErr((xmlSchemaAbstractCtxtPtr) vctxt, "xmlSchemaVAttributesComplex"
, "calling xmlSchemaCopyValue()");
25500 "calling xmlSchemaCopyValue()")xmlSchemaInternalErr((xmlSchemaAbstractCtxtPtr) vctxt, "xmlSchemaVAttributesComplex"
, "calling xmlSchemaCopyValue()");
;
25501 goto internal_error;
25502 }
25503 }
25504 /*
25505 * PSVI: Add the default attribute to the current element.
25506 * VAL TODO: Should we use the *normalized* value? This currently
25507 * uses the *initial* value.
25508 */
25509
25510 if (defAttrOwnerElem) {
25511 xmlChar *normValue;
25512 const xmlChar *value;
25513
25514 value = iattr->value;
25515 /*
25516 * Normalize the value.
25517 */
25518 normValue = xmlSchemaNormalizeValue(iattr->typeDef,
25519 iattr->value);
25520 if (normValue != NULL((void*)0))
25521 value = BAD_CAST(xmlChar *) normValue;
25522
25523 if (iattr->nsName == NULL((void*)0)) {
25524 if (xmlNewProp(defAttrOwnerElem,
25525 iattr->localName, value) == NULL((void*)0)) {
25526 VERROR_INT("xmlSchemaVAttributesComplex",xmlSchemaInternalErr((xmlSchemaAbstractCtxtPtr) vctxt, "xmlSchemaVAttributesComplex"
, "calling xmlNewProp()");
25527 "calling xmlNewProp()")xmlSchemaInternalErr((xmlSchemaAbstractCtxtPtr) vctxt, "xmlSchemaVAttributesComplex"
, "calling xmlNewProp()");
;
25528 if (normValue != NULL((void*)0))
25529 xmlFree(normValue);
25530 goto internal_error;
25531 }
25532 } else {
25533 xmlNsPtr ns;
25534
25535 ns = xmlSearchNsByHref(defAttrOwnerElem->doc,
25536 defAttrOwnerElem, iattr->nsName);
25537 if (ns == NULL((void*)0)) {
25538 xmlChar prefix[12];
25539 int counter = 0;
25540
25541 /*
25542 * Create a namespace declaration on the validation
25543 * root node if no namespace declaration is in scope.
25544 */
25545 do {
25546 snprintf((char *) prefix, 12, "p%d", counter++);
25547 ns = xmlSearchNs(defAttrOwnerElem->doc,
25548 defAttrOwnerElem, BAD_CAST(xmlChar *) prefix);
25549 if (counter > 1000) {
25550 VERROR_INT(xmlSchemaInternalErr((xmlSchemaAbstractCtxtPtr) vctxt, "xmlSchemaVAttributesComplex"
, "could not compute a ns prefix for a " "default/fixed attribute"
);
25551 "xmlSchemaVAttributesComplex",xmlSchemaInternalErr((xmlSchemaAbstractCtxtPtr) vctxt, "xmlSchemaVAttributesComplex"
, "could not compute a ns prefix for a " "default/fixed attribute"
);
25552 "could not compute a ns prefix for a "xmlSchemaInternalErr((xmlSchemaAbstractCtxtPtr) vctxt, "xmlSchemaVAttributesComplex"
, "could not compute a ns prefix for a " "default/fixed attribute"
);
25553 "default/fixed attribute")xmlSchemaInternalErr((xmlSchemaAbstractCtxtPtr) vctxt, "xmlSchemaVAttributesComplex"
, "could not compute a ns prefix for a " "default/fixed attribute"
);
;
25554 if (normValue != NULL((void*)0))
25555 xmlFree(normValue);
25556 goto internal_error;
25557 }
25558 } while (ns != NULL((void*)0));
25559 ns = xmlNewNs(vctxt->validationRoot,
25560 iattr->nsName, BAD_CAST(xmlChar *) prefix);
25561 }
25562 /*
25563 * TODO:
25564 * http://lists.w3.org/Archives/Public/www-xml-schema-comments/2005JulSep/0406.html
25565 * If we have QNames: do we need to ensure there's a
25566 * prefix defined for the QName?
25567 */
25568 xmlNewNsProp(defAttrOwnerElem, ns, iattr->localName, value);
25569 }
25570 if (normValue != NULL((void*)0))
25571 xmlFree(normValue);
25572 }
25573 /*
25574 * Go directly to IDC evaluation.
25575 */
25576 goto eval_idcs;
25577 }
25578 /*
25579 * Validate the value.
25580 */
25581 if (vctxt->value != NULL((void*)0)) {
25582 /*
25583 * Free last computed value; just for safety reasons.
25584 */
25585 xmlSchemaFreeValue(vctxt->value);
25586 vctxt->value = NULL((void*)0);
25587 }
25588 /*
25589 * Note that the attribute *use* can be unavailable, if
25590 * the attribute was a wild attribute.
25591 */
25592 if ((iattr->decl->flags & XML_SCHEMAS_ATTR_FIXED1 << 9) ||
25593 ((iattr->use != NULL((void*)0)) &&
25594 (iattr->use->flags & XML_SCHEMAS_ATTR_FIXED1 << 9)))
25595 fixed = 1;
25596 else
25597 fixed = 0;
25598 /*
25599 * SPEC (cvc-attribute)
25600 * (3) "The item's `normalized value` must be locally `valid`
25601 * with respect to that {type definition} as per
25602 * String Valid ($3.14.4)."
25603 *
25604 * VAL TODO: Do we already have the
25605 * "normalized attribute value" here?
25606 */
25607 if (xpathRes || fixed) {
25608 iattr->flags |= XML_SCHEMA_NODE_INFO_VALUE_NEEDED1<<4;
25609 /*
25610 * Request a computed value.
25611 */
25612 res = xmlSchemaVCheckCVCSimpleType(
25613 ACTXT_CAST(xmlSchemaAbstractCtxtPtr) vctxt,
25614 iattr->node, iattr->typeDef, iattr->value, &(iattr->val),
25615 1, 1, 0);
25616 } else {
25617 res = xmlSchemaVCheckCVCSimpleType(
25618 ACTXT_CAST(xmlSchemaAbstractCtxtPtr) vctxt,
25619 iattr->node, iattr->typeDef, iattr->value, NULL((void*)0),
25620 1, 0, 0);
25621 }
25622
25623 if (res != 0) {
25624 if (res == -1) {
25625 VERROR_INT("xmlSchemaVAttributesComplex",xmlSchemaInternalErr((xmlSchemaAbstractCtxtPtr) vctxt, "xmlSchemaVAttributesComplex"
, "calling xmlSchemaStreamValidateSimpleTypeValue()");
25626 "calling xmlSchemaStreamValidateSimpleTypeValue()")xmlSchemaInternalErr((xmlSchemaAbstractCtxtPtr) vctxt, "xmlSchemaVAttributesComplex"
, "calling xmlSchemaStreamValidateSimpleTypeValue()");
;
25627 goto internal_error;
25628 }
25629 iattr->state = XML_SCHEMAS_ATTR_INVALID_VALUE5;
25630 /*
25631 * SPEC PSVI Assessment Outcome (Attribute)
25632 * [validity] = "invalid"
25633 */
25634 goto eval_idcs;
25635 }
25636
25637 if (fixed) {
25638 /*
25639 * SPEC Attribute Locally Valid (Use) (cvc-au)
25640 * "For an attribute information item to be `valid`
25641 * with respect to an attribute use its *normalized*
25642 * value must match the *canonical* lexical
25643 * representation of the attribute use's {value
25644 * constraint}value, if it is present and fixed."
25645 *
25646 * VAL TODO: The requirement for the *canonical* value
25647 * will be removed in XML Schema 1.1.
25648 */
25649 /*
25650 * SPEC Attribute Locally Valid (cvc-attribute)
25651 * (4) "The item's *actual* value must match the *value* of
25652 * the {value constraint}, if it is present and fixed."
25653 */
25654 if (iattr->val == NULL((void*)0)) {
25655 /* VAL TODO: A value was not precomputed. */
25656 TODO(*__xmlGenericError())((*__xmlGenericErrorContext()), "Unimplemented block at %s:%d\n"
, "xmlschemas.c", 25656);
25657 goto eval_idcs;
25658 }
25659 if ((iattr->use != NULL((void*)0)) &&
25660 (iattr->use->defValue != NULL((void*)0))) {
25661 if (iattr->use->defVal == NULL((void*)0)) {
25662 /* VAL TODO: A default value was not precomputed. */
25663 TODO(*__xmlGenericError())((*__xmlGenericErrorContext()), "Unimplemented block at %s:%d\n"
, "xmlschemas.c", 25663);
25664 goto eval_idcs;
25665 }
25666 iattr->vcValue = iattr->use->defValue;
25667 /*
25668 if (xmlSchemaCompareValuesWhtsp(attr->val,
25669 (xmlSchemaWhitespaceValueType) ws,
25670 attr->use->defVal,
25671 (xmlSchemaWhitespaceValueType) ws) != 0) {
25672 */
25673 if (! xmlSchemaAreValuesEqual(iattr->val, iattr->use->defVal))
25674 iattr->state = XML_SCHEMAS_ATTR_ERR_FIXED_VALUE7;
25675 } else {
25676 if (iattr->decl->defVal == NULL((void*)0)) {
25677 /* VAL TODO: A default value was not precomputed. */
25678 TODO(*__xmlGenericError())((*__xmlGenericErrorContext()), "Unimplemented block at %s:%d\n"
, "xmlschemas.c", 25678);
25679 goto eval_idcs;
25680 }
25681 iattr->vcValue = iattr->decl->defValue;
25682 /*
25683 if (xmlSchemaCompareValuesWhtsp(attr->val,
25684 (xmlSchemaWhitespaceValueType) ws,
25685 attrDecl->defVal,
25686 (xmlSchemaWhitespaceValueType) ws) != 0) {
25687 */
25688 if (! xmlSchemaAreValuesEqual(iattr->val, iattr->decl->defVal))
25689 iattr->state = XML_SCHEMAS_ATTR_ERR_FIXED_VALUE7;
25690 }
25691 /*
25692 * [validity] = "valid"
25693 */
25694 }
25695eval_idcs:
25696 /*
25697 * Evaluate IDCs.
25698 */
25699 if (xpathRes) {
25700 if (xmlSchemaXPathProcessHistory(vctxt,
25701 vctxt->depth +1) == -1) {
25702 VERROR_INT("xmlSchemaVAttributesComplex",xmlSchemaInternalErr((xmlSchemaAbstractCtxtPtr) vctxt, "xmlSchemaVAttributesComplex"
, "calling xmlSchemaXPathEvaluate()");
25703 "calling xmlSchemaXPathEvaluate()")xmlSchemaInternalErr((xmlSchemaAbstractCtxtPtr) vctxt, "xmlSchemaVAttributesComplex"
, "calling xmlSchemaXPathEvaluate()");
;
25704 goto internal_error;
25705 }
25706 } else if (vctxt->xpathStates != NULL((void*)0))
25707 xmlSchemaXPathPop(vctxt);
25708 }
25709
25710 /*
25711 * Report errors.
25712 */
25713 for (i = 0; i < vctxt->nbAttrInfos; i++) {
25714 iattr = vctxt->attrInfos[i];
25715 if ((iattr->state == XML_SCHEMAS_ATTR_META17) ||
25716 (iattr->state == XML_SCHEMAS_ATTR_ASSESSED2) ||
25717 (iattr->state == XML_SCHEMAS_ATTR_WILD_SKIP13) ||
25718 (iattr->state == XML_SCHEMAS_ATTR_WILD_LAX_NO_DECL14))
25719 continue;
25720 ACTIVATE_ATTRIBUTE(iattr)vctxt->inode = (xmlSchemaNodeInfoPtr) iattr;;
25721 switch (iattr->state) {
25722 case XML_SCHEMAS_ATTR_ERR_MISSING4: {
25723 xmlChar *str = NULL((void*)0);
25724 ACTIVATE_ELEMvctxt->inode = vctxt->elemInfos[vctxt->depth];;
25725 xmlSchemaCustomErr(ACTXT_CAST(xmlSchemaAbstractCtxtPtr) vctxt,
25726 XML_SCHEMAV_CVC_COMPLEX_TYPE_4, NULL((void*)0), NULL((void*)0),
25727 "The attribute '%s' is required but missing",
25728 xmlSchemaFormatQName(&str,
25729 iattr->decl->targetNamespace,
25730 iattr->decl->name),
25731 NULL((void*)0));
25732 FREE_AND_NULL(str)if ((str) != ((void*)0)) { xmlFree((xmlChar *) (str)); str = (
(void*)0); }
25733 break;
25734 }
25735 case XML_SCHEMAS_ATTR_ERR_NO_TYPE6:
25736 VERROR(XML_SCHEMAV_CVC_ATTRIBUTE_2, NULL,xmlSchemaCustomErr((xmlSchemaAbstractCtxtPtr) vctxt, XML_SCHEMAV_CVC_ATTRIBUTE_2
, ((void*)0), ((void*)0), "The type definition is absent", ((
void*)0), ((void*)0));
25737 "The type definition is absent")xmlSchemaCustomErr((xmlSchemaAbstractCtxtPtr) vctxt, XML_SCHEMAV_CVC_ATTRIBUTE_2
, ((void*)0), ((void*)0), "The type definition is absent", ((
void*)0), ((void*)0));
;
25738 break;
25739 case XML_SCHEMAS_ATTR_ERR_FIXED_VALUE7:
25740 xmlSchemaCustomErr(ACTXT_CAST(xmlSchemaAbstractCtxtPtr) vctxt,
25741 XML_SCHEMAV_CVC_AU, NULL((void*)0), NULL((void*)0),
25742 "The value '%s' does not match the fixed "
25743 "value constraint '%s'",
25744 iattr->value, iattr->vcValue);
25745 break;
25746 case XML_SCHEMAS_ATTR_ERR_WILD_STRICT_NO_DECL10:
25747 VERROR(XML_SCHEMAV_CVC_WILDCARD, NULL,xmlSchemaCustomErr((xmlSchemaAbstractCtxtPtr) vctxt, XML_SCHEMAV_CVC_WILDCARD
, ((void*)0), ((void*)0), "No matching global attribute declaration available, but "
"demanded by the strict wildcard", ((void*)0), ((void*)0));
25748 "No matching global attribute declaration available, but "xmlSchemaCustomErr((xmlSchemaAbstractCtxtPtr) vctxt, XML_SCHEMAV_CVC_WILDCARD
, ((void*)0), ((void*)0), "No matching global attribute declaration available, but "
"demanded by the strict wildcard", ((void*)0), ((void*)0));
25749 "demanded by the strict wildcard")xmlSchemaCustomErr((xmlSchemaAbstractCtxtPtr) vctxt, XML_SCHEMAV_CVC_WILDCARD
, ((void*)0), ((void*)0), "No matching global attribute declaration available, but "
"demanded by the strict wildcard", ((void*)0), ((void*)0));
;
25750 break;
25751 case XML_SCHEMAS_ATTR_UNKNOWN1:
25752 if (iattr->metaType)
25753 break;
25754 /*
25755 * MAYBE VAL TODO: One might report different error messages
25756 * for the following errors.
25757 */
25758 if (type->attributeWildcard == NULL((void*)0)) {
25759 xmlSchemaIllegalAttrErr(ACTXT_CAST(xmlSchemaAbstractCtxtPtr) vctxt,
25760 XML_SCHEMAV_CVC_COMPLEX_TYPE_3_2_1, iattr, NULL((void*)0));
25761 } else {
25762 xmlSchemaIllegalAttrErr(ACTXT_CAST(xmlSchemaAbstractCtxtPtr) vctxt,
25763 XML_SCHEMAV_CVC_COMPLEX_TYPE_3_2_2, iattr, NULL((void*)0));
25764 }
25765 break;
25766 default:
25767 break;
25768 }
25769 }
25770
25771 ACTIVATE_ELEMvctxt->inode = vctxt->elemInfos[vctxt->depth];;
25772 return (0);
25773internal_error:
25774 ACTIVATE_ELEMvctxt->inode = vctxt->elemInfos[vctxt->depth];;
25775 return (-1);
25776}
25777
25778static int
25779xmlSchemaValidateElemWildcard(xmlSchemaValidCtxtPtr vctxt,
25780 int *skip)
25781{
25782 xmlSchemaWildcardPtr wild = (xmlSchemaWildcardPtr) vctxt->inode->decl;
25783 /*
25784 * The namespace of the element was already identified to be
25785 * matching the wildcard.
25786 */
25787 if ((skip == NULL((void*)0)) || (wild == NULL((void*)0)) ||
25788 (wild->type != XML_SCHEMA_TYPE_ANY)) {
25789 VERROR_INT("xmlSchemaValidateElemWildcard",xmlSchemaInternalErr((xmlSchemaAbstractCtxtPtr) vctxt, "xmlSchemaValidateElemWildcard"
, "bad arguments");
25790 "bad arguments")xmlSchemaInternalErr((xmlSchemaAbstractCtxtPtr) vctxt, "xmlSchemaValidateElemWildcard"
, "bad arguments");
;
25791 return (-1);
25792 }
25793 *skip = 0;
25794 if (wild->processContents == XML_SCHEMAS_ANY_SKIP1) {
25795 /*
25796 * URGENT VAL TODO: Either we need to position the stream to the
25797 * next sibling, or walk the whole subtree.
25798 */
25799 *skip = 1;
25800 return (0);
25801 }
25802 {
25803 xmlSchemaElementPtr decl = NULL((void*)0);
25804
25805 decl = xmlSchemaGetElem(vctxt->schema,
25806 vctxt->inode->localName, vctxt->inode->nsName);
25807 if (decl != NULL((void*)0)) {
25808 vctxt->inode->decl = decl;
25809 return (0);
25810 }
25811 }
25812 if (wild->processContents == XML_SCHEMAS_ANY_STRICT3) {
25813 /* VAL TODO: Change to proper error code. */
25814 VERROR(XML_SCHEMAV_CVC_ELT_1, NULL, /* WXS_BASIC_CAST wild */xmlSchemaCustomErr((xmlSchemaAbstractCtxtPtr) vctxt, XML_SCHEMAV_CVC_ELT_1
, ((void*)0), ((void*)0), "No matching global element declaration available, but "
"demanded by the strict wildcard", ((void*)0), ((void*)0));
25815 "No matching global element declaration available, but "xmlSchemaCustomErr((xmlSchemaAbstractCtxtPtr) vctxt, XML_SCHEMAV_CVC_ELT_1
, ((void*)0), ((void*)0), "No matching global element declaration available, but "
"demanded by the strict wildcard", ((void*)0), ((void*)0));
25816 "demanded by the strict wildcard")xmlSchemaCustomErr((xmlSchemaAbstractCtxtPtr) vctxt, XML_SCHEMAV_CVC_ELT_1
, ((void*)0), ((void*)0), "No matching global element declaration available, but "
"demanded by the strict wildcard", ((void*)0), ((void*)0));
;
25817 return (vctxt->err);
25818 }
25819 if (vctxt->nbAttrInfos != 0) {
25820 xmlSchemaAttrInfoPtr iattr;
25821 /*
25822 * SPEC Validation Rule: Schema-Validity Assessment (Element)
25823 * (1.2.1.2.1) - (1.2.1.2.3 )
25824 *
25825 * Use the xsi:type attribute for the type definition.
25826 */
25827 iattr = xmlSchemaGetMetaAttrInfo(vctxt,
25828 XML_SCHEMA_ATTR_INFO_META_XSI_TYPE1);
25829 if (iattr != NULL((void*)0)) {
25830 if (xmlSchemaProcessXSIType(vctxt, iattr,
25831 &(vctxt->inode->typeDef), NULL((void*)0)) == -1) {
25832 VERROR_INT("xmlSchemaValidateElemWildcard",xmlSchemaInternalErr((xmlSchemaAbstractCtxtPtr) vctxt, "xmlSchemaValidateElemWildcard"
, "calling xmlSchemaProcessXSIType() to " "process the attribute 'xsi:nil'"
);
25833 "calling xmlSchemaProcessXSIType() to "xmlSchemaInternalErr((xmlSchemaAbstractCtxtPtr) vctxt, "xmlSchemaValidateElemWildcard"
, "calling xmlSchemaProcessXSIType() to " "process the attribute 'xsi:nil'"
);
25834 "process the attribute 'xsi:nil'")xmlSchemaInternalErr((xmlSchemaAbstractCtxtPtr) vctxt, "xmlSchemaValidateElemWildcard"
, "calling xmlSchemaProcessXSIType() to " "process the attribute 'xsi:nil'"
);
;
25835 return (-1);
25836 }
25837 /*
25838 * Don't return an error on purpose.
25839 */
25840 return (0);
25841 }
25842 }
25843 /*
25844 * SPEC Validation Rule: Schema-Validity Assessment (Element)
25845 *
25846 * Fallback to "anyType".
25847 */
25848 vctxt->inode->typeDef =
25849 xmlSchemaGetBuiltInType(XML_SCHEMAS_ANYTYPE);
25850 return (0);
25851}
25852
25853/*
25854* xmlSchemaCheckCOSValidDefault:
25855*
25856* This will be called if: not nilled, no content and a default/fixed
25857* value is provided.
25858*/
25859
25860static int
25861xmlSchemaCheckCOSValidDefault(xmlSchemaValidCtxtPtr vctxt,
25862 const xmlChar *value,
25863 xmlSchemaValPtr *val)
25864{
25865 int ret = 0;
25866 xmlSchemaNodeInfoPtr inode = vctxt->inode;
25867
25868 /*
25869 * cos-valid-default:
25870 * Schema Component Constraint: Element Default Valid (Immediate)
25871 * For a string to be a valid default with respect to a type
25872 * definition the appropriate case among the following must be true:
25873 */
25874 if WXS_IS_COMPLEX(inode->typeDef)(((inode->typeDef)->type == XML_SCHEMA_TYPE_COMPLEX) ||
((inode->typeDef)->builtInType == XML_SCHEMAS_ANYTYPE)
)
{
25875 /*
25876 * Complex type.
25877 *
25878 * SPEC (2.1) "its {content type} must be a simple type definition
25879 * or mixed."
25880 * SPEC (2.2.2) "If the {content type} is mixed, then the {content
25881 * type}'s particle must be `emptiable` as defined by
25882 * Particle Emptiable ($3.9.6)."
25883 */
25884 if ((! WXS_HAS_SIMPLE_CONTENT(inode->typeDef)((inode->typeDef->contentType == XML_SCHEMA_CONTENT_SIMPLE
) || (inode->typeDef->contentType == XML_SCHEMA_CONTENT_BASIC
))
) &&
25885 ((! WXS_HAS_MIXED_CONTENT(inode->typeDef)(inode->typeDef->contentType == XML_SCHEMA_CONTENT_MIXED
)
) ||
25886 (! WXS_EMPTIABLE(inode->typeDef)(xmlSchemaIsParticleEmptiable((xmlSchemaParticlePtr) (inode->
typeDef)->subtypes))
))) {
25887 ret = XML_SCHEMAP_COS_VALID_DEFAULT_2_1;
25888 /* NOTE that this covers (2.2.2) as well. */
25889 VERROR(ret, NULL,xmlSchemaCustomErr((xmlSchemaAbstractCtxtPtr) vctxt, ret, ((void
*)0), ((void*)0), "For a string to be a valid default, the type definition "
"must be a simple type or a complex type with simple content "
"or mixed content and a particle emptiable", ((void*)0), ((void
*)0));
25890 "For a string to be a valid default, the type definition "xmlSchemaCustomErr((xmlSchemaAbstractCtxtPtr) vctxt, ret, ((void
*)0), ((void*)0), "For a string to be a valid default, the type definition "
"must be a simple type or a complex type with simple content "
"or mixed content and a particle emptiable", ((void*)0), ((void
*)0));
25891 "must be a simple type or a complex type with simple content "xmlSchemaCustomErr((xmlSchemaAbstractCtxtPtr) vctxt, ret, ((void
*)0), ((void*)0), "For a string to be a valid default, the type definition "
"must be a simple type or a complex type with simple content "
"or mixed content and a particle emptiable", ((void*)0), ((void
*)0));
25892 "or mixed content and a particle emptiable")xmlSchemaCustomErr((xmlSchemaAbstractCtxtPtr) vctxt, ret, ((void
*)0), ((void*)0), "For a string to be a valid default, the type definition "
"must be a simple type or a complex type with simple content "
"or mixed content and a particle emptiable", ((void*)0), ((void
*)0));
;
25893 return(ret);
25894 }
25895 }
25896 /*
25897 * 1 If the type definition is a simple type definition, then the string
25898 * must be `valid` with respect to that definition as defined by String
25899 * Valid ($3.14.4).
25900 *
25901 * AND
25902 *
25903 * 2.2.1 If the {content type} is a simple type definition, then the
25904 * string must be `valid` with respect to that simple type definition
25905 * as defined by String Valid ($3.14.4).
25906 */
25907 if (WXS_IS_SIMPLE(inode->typeDef)((inode->typeDef->type == XML_SCHEMA_TYPE_SIMPLE) || ((
inode->typeDef->type == XML_SCHEMA_TYPE_BASIC) &&
(inode->typeDef->builtInType != XML_SCHEMAS_ANYTYPE)))
) {
25908
25909 ret = xmlSchemaVCheckCVCSimpleType(ACTXT_CAST(xmlSchemaAbstractCtxtPtr) vctxt,
25910 NULL((void*)0), inode->typeDef, value, val, 1, 1, 0);
25911
25912 } else if (WXS_HAS_SIMPLE_CONTENT(inode->typeDef)((inode->typeDef->contentType == XML_SCHEMA_CONTENT_SIMPLE
) || (inode->typeDef->contentType == XML_SCHEMA_CONTENT_BASIC
))
) {
25913
25914 ret = xmlSchemaVCheckCVCSimpleType(ACTXT_CAST(xmlSchemaAbstractCtxtPtr) vctxt,
25915 NULL((void*)0), inode->typeDef->contentTypeDef, value, val, 1, 1, 0);
25916 }
25917 if (ret < 0) {
25918 VERROR_INT("xmlSchemaCheckCOSValidDefault",xmlSchemaInternalErr((xmlSchemaAbstractCtxtPtr) vctxt, "xmlSchemaCheckCOSValidDefault"
, "calling xmlSchemaVCheckCVCSimpleType()");
25919 "calling xmlSchemaVCheckCVCSimpleType()")xmlSchemaInternalErr((xmlSchemaAbstractCtxtPtr) vctxt, "xmlSchemaCheckCOSValidDefault"
, "calling xmlSchemaVCheckCVCSimpleType()");
;
25920 }
25921 return (ret);
25922}
25923
25924static void
25925xmlSchemaVContentModelCallback(xmlRegExecCtxtPtr exec ATTRIBUTE_UNUSED__attribute__((unused)),
25926 const xmlChar * name ATTRIBUTE_UNUSED__attribute__((unused)),
25927 void *transdata, void *inputdata)
25928{
25929 xmlSchemaElementPtr item = (xmlSchemaElementPtr) transdata;
25930 xmlSchemaNodeInfoPtr inode = (xmlSchemaNodeInfoPtr) inputdata;
25931 inode->decl = item;
25932}
25933
25934static int
25935xmlSchemaValidatorPushElem(xmlSchemaValidCtxtPtr vctxt)
25936{
25937 vctxt->inode = xmlSchemaGetFreshElemInfo(vctxt);
25938 if (vctxt->inode == NULL((void*)0)) {
25939 VERROR_INT("xmlSchemaValidatorPushElem",xmlSchemaInternalErr((xmlSchemaAbstractCtxtPtr) vctxt, "xmlSchemaValidatorPushElem"
, "calling xmlSchemaGetFreshElemInfo()");
25940 "calling xmlSchemaGetFreshElemInfo()")xmlSchemaInternalErr((xmlSchemaAbstractCtxtPtr) vctxt, "xmlSchemaValidatorPushElem"
, "calling xmlSchemaGetFreshElemInfo()");
;
25941 return (-1);
25942 }
25943 vctxt->nbAttrInfos = 0;
25944 return (0);
25945}
25946
25947static int
25948xmlSchemaVCheckINodeDataType(xmlSchemaValidCtxtPtr vctxt,
25949 xmlSchemaNodeInfoPtr inode,
25950 xmlSchemaTypePtr type,
25951 const xmlChar *value)
25952{
25953 if (inode->flags & XML_SCHEMA_NODE_INFO_VALUE_NEEDED1<<4)
25954 return (xmlSchemaVCheckCVCSimpleType(
25955 ACTXT_CAST(xmlSchemaAbstractCtxtPtr) vctxt, NULL((void*)0),
25956 type, value, &(inode->val), 1, 1, 0));
25957 else
25958 return (xmlSchemaVCheckCVCSimpleType(
25959 ACTXT_CAST(xmlSchemaAbstractCtxtPtr) vctxt, NULL((void*)0),
25960 type, value, NULL((void*)0), 1, 0, 0));
25961}
25962
25963
25964
25965/*
25966* Process END of element.
25967*/
25968static int
25969xmlSchemaValidatorPopElem(xmlSchemaValidCtxtPtr vctxt)
25970{
25971 int ret = 0;
25972 xmlSchemaNodeInfoPtr inode = vctxt->inode;
25973
25974 if (vctxt->nbAttrInfos != 0)
25975 xmlSchemaClearAttrInfos(vctxt);
25976 if (inode->flags & XML_SCHEMA_NODE_INFO_ERR_NOT_EXPECTED1<<9) {
25977 /*
25978 * This element was not expected;
25979 * we will not validate child elements of broken parents.
25980 * Skip validation of all content of the parent.
25981 */
25982 vctxt->skipDepth = vctxt->depth -1;
25983 goto end_elem;
25984 }
25985 if ((inode->typeDef == NULL((void*)0)) ||
25986 (inode->flags & XML_SCHEMA_NODE_INFO_ERR_BAD_TYPE1<<10)) {
25987 /*
25988 * 1. the type definition might be missing if the element was
25989 * error prone
25990 * 2. it might be abstract.
25991 */
25992 goto end_elem;
25993 }
25994 /*
25995 * Check the content model.
25996 */
25997 if ((inode->typeDef->contentType == XML_SCHEMA_CONTENT_MIXED) ||
25998 (inode->typeDef->contentType == XML_SCHEMA_CONTENT_ELEMENTS)) {
25999
26000 /*
26001 * Workaround for "anyType".
26002 */
26003 if (inode->typeDef->builtInType == XML_SCHEMAS_ANYTYPE)
26004 goto character_content;
26005
26006 if ((inode->flags & XML_SCHEMA_ELEM_INFO_ERR_BAD_CONTENT1<<8) == 0) {
26007 xmlChar *values[10];
26008 int terminal, nbval = 10, nbneg;
26009
26010 if (inode->regexCtxt == NULL((void*)0)) {
26011 /*
26012 * Create the regex context.
26013 */
26014 inode->regexCtxt =
26015 xmlRegNewExecCtxt(inode->typeDef->contModel,
26016 xmlSchemaVContentModelCallback, vctxt);
26017 if (inode->regexCtxt == NULL((void*)0)) {
26018 VERROR_INT("xmlSchemaValidatorPopElem",xmlSchemaInternalErr((xmlSchemaAbstractCtxtPtr) vctxt, "xmlSchemaValidatorPopElem"
, "failed to create a regex context");
26019 "failed to create a regex context")xmlSchemaInternalErr((xmlSchemaAbstractCtxtPtr) vctxt, "xmlSchemaValidatorPopElem"
, "failed to create a regex context");
;
26020 goto internal_error;
26021 }
26022 }
26023
26024 /*
26025 * Do not check further content if the node has been nilled
26026 */
26027 if (INODE_NILLED(inode)(inode->flags & 1<<2)) {
26028 ret = 0;
26029 goto skip_nilled;
26030 }
26031
26032 /*
26033 * Get hold of the still expected content, since a further
26034 * call to xmlRegExecPushString() will lose this information.
26035 */
26036 xmlRegExecNextValues(inode->regexCtxt,
26037 &nbval, &nbneg, &values[0], &terminal);
26038 ret = xmlRegExecPushString(inode->regexCtxt, NULL((void*)0), NULL((void*)0));
26039 if ((ret<0) || ((ret==0) && (!INODE_NILLED(inode)(inode->flags & 1<<2)))) {
26040 /*
26041 * Still missing something.
26042 */
26043 ret = 1;
26044 inode->flags |=
26045 XML_SCHEMA_ELEM_INFO_ERR_BAD_CONTENT1<<8;
26046 xmlSchemaComplexTypeErr(ACTXT_CAST(xmlSchemaAbstractCtxtPtr) vctxt,
26047 XML_SCHEMAV_ELEMENT_CONTENT, NULL((void*)0), NULL((void*)0),
26048 "Missing child element(s)",
26049 nbval, nbneg, values);
26050 } else {
26051 /*
26052 * Content model is satisfied.
26053 */
26054 ret = 0;
26055 }
26056
26057 }
26058 }
26059
26060skip_nilled:
26061
26062 if (inode->typeDef->contentType == XML_SCHEMA_CONTENT_ELEMENTS)
26063 goto end_elem;
26064
26065character_content:
26066
26067 if (vctxt->value != NULL((void*)0)) {
26068 xmlSchemaFreeValue(vctxt->value);
26069 vctxt->value = NULL((void*)0);
26070 }
26071 /*
26072 * Check character content.
26073 */
26074 if (inode->decl == NULL((void*)0)) {
26075 /*
26076 * Speedup if no declaration exists.
26077 */
26078 if (WXS_IS_SIMPLE(inode->typeDef)((inode->typeDef->type == XML_SCHEMA_TYPE_SIMPLE) || ((
inode->typeDef->type == XML_SCHEMA_TYPE_BASIC) &&
(inode->typeDef->builtInType != XML_SCHEMAS_ANYTYPE)))
) {
26079 ret = xmlSchemaVCheckINodeDataType(vctxt,
26080 inode, inode->typeDef, inode->value);
26081 } else if (WXS_HAS_SIMPLE_CONTENT(inode->typeDef)((inode->typeDef->contentType == XML_SCHEMA_CONTENT_SIMPLE
) || (inode->typeDef->contentType == XML_SCHEMA_CONTENT_BASIC
))
) {
26082 ret = xmlSchemaVCheckINodeDataType(vctxt,
26083 inode, inode->typeDef->contentTypeDef,
26084 inode->value);
26085 }
26086 if (ret < 0) {
26087 VERROR_INT("xmlSchemaValidatorPopElem",xmlSchemaInternalErr((xmlSchemaAbstractCtxtPtr) vctxt, "xmlSchemaValidatorPopElem"
, "calling xmlSchemaVCheckCVCSimpleType()");
26088 "calling xmlSchemaVCheckCVCSimpleType()")xmlSchemaInternalErr((xmlSchemaAbstractCtxtPtr) vctxt, "xmlSchemaValidatorPopElem"
, "calling xmlSchemaVCheckCVCSimpleType()");
;
26089 goto internal_error;
26090 }
26091 goto end_elem;
26092 }
26093 /*
26094 * cvc-elt (3.3.4) : 5
26095 * The appropriate case among the following must be true:
26096 */
26097 /*
26098 * cvc-elt (3.3.4) : 5.1
26099 * If the declaration has a {value constraint},
26100 * the item has neither element nor character [children] and
26101 * clause 3.2 has not applied, then all of the following must be true:
26102 */
26103 if ((inode->decl->value != NULL((void*)0)) &&
26104 (inode->flags & XML_SCHEMA_ELEM_INFO_EMPTY1<<5) &&
26105 (! INODE_NILLED(inode)(inode->flags & 1<<2))) {
26106 /*
26107 * cvc-elt (3.3.4) : 5.1.1
26108 * If the `actual type definition` is a `local type definition`
26109 * then the canonical lexical representation of the {value constraint}
26110 * value must be a valid default for the `actual type definition` as
26111 * defined in Element Default Valid (Immediate) ($3.3.6).
26112 */
26113 /*
26114 * NOTE: 'local' above means types acquired by xsi:type.
26115 * NOTE: Although the *canonical* value is stated, it is not
26116 * relevant if canonical or not. Additionally XML Schema 1.1
26117 * will removed this requirement as well.
26118 */
26119 if (inode->flags & XML_SCHEMA_ELEM_INFO_LOCAL_TYPE1<<3) {
26120
26121 ret = xmlSchemaCheckCOSValidDefault(vctxt,
26122 inode->decl->value, &(inode->val));
26123 if (ret != 0) {
26124 if (ret < 0) {
26125 VERROR_INT("xmlSchemaValidatorPopElem",xmlSchemaInternalErr((xmlSchemaAbstractCtxtPtr) vctxt, "xmlSchemaValidatorPopElem"
, "calling xmlSchemaCheckCOSValidDefault()");
26126 "calling xmlSchemaCheckCOSValidDefault()")xmlSchemaInternalErr((xmlSchemaAbstractCtxtPtr) vctxt, "xmlSchemaValidatorPopElem"
, "calling xmlSchemaCheckCOSValidDefault()");
;
26127 goto internal_error;
26128 }
26129 goto end_elem;
26130 }
26131 /*
26132 * Stop here, to avoid redundant validation of the value
26133 * (see following).
26134 */
26135 goto default_psvi;
26136 }
26137 /*
26138 * cvc-elt (3.3.4) : 5.1.2
26139 * The element information item with the canonical lexical
26140 * representation of the {value constraint} value used as its
26141 * `normalized value` must be `valid` with respect to the
26142 * `actual type definition` as defined by Element Locally Valid (Type)
26143 * ($3.3.4).
26144 */
26145 if (WXS_IS_SIMPLE(inode->typeDef)((inode->typeDef->type == XML_SCHEMA_TYPE_SIMPLE) || ((
inode->typeDef->type == XML_SCHEMA_TYPE_BASIC) &&
(inode->typeDef->builtInType != XML_SCHEMAS_ANYTYPE)))
) {
26146 ret = xmlSchemaVCheckINodeDataType(vctxt,
26147 inode, inode->typeDef, inode->decl->value);
26148 } else if (WXS_HAS_SIMPLE_CONTENT(inode->typeDef)((inode->typeDef->contentType == XML_SCHEMA_CONTENT_SIMPLE
) || (inode->typeDef->contentType == XML_SCHEMA_CONTENT_BASIC
))
) {
26149 ret = xmlSchemaVCheckINodeDataType(vctxt,
26150 inode, inode->typeDef->contentTypeDef,
26151 inode->decl->value);
26152 }
26153 if (ret != 0) {
26154 if (ret < 0) {
26155 VERROR_INT("xmlSchemaValidatorPopElem",xmlSchemaInternalErr((xmlSchemaAbstractCtxtPtr) vctxt, "xmlSchemaValidatorPopElem"
, "calling xmlSchemaVCheckCVCSimpleType()");
26156 "calling xmlSchemaVCheckCVCSimpleType()")xmlSchemaInternalErr((xmlSchemaAbstractCtxtPtr) vctxt, "xmlSchemaValidatorPopElem"
, "calling xmlSchemaVCheckCVCSimpleType()");
;
26157 goto internal_error;
26158 }
26159 goto end_elem;
26160 }
26161
26162default_psvi:
26163 /*
26164 * PSVI: Create a text node on the instance element.
26165 */
26166 if ((vctxt->options & XML_SCHEMA_VAL_VC_I_CREATE) &&
26167 (inode->node != NULL((void*)0))) {
26168 xmlNodePtr textChild;
26169 xmlChar *normValue;
26170 /*
26171 * VAL TODO: Normalize the value.
26172 */
26173 normValue = xmlSchemaNormalizeValue(inode->typeDef,
26174 inode->decl->value);
26175 if (normValue != NULL((void*)0)) {
26176 textChild = xmlNewDocText(inode->node->doc,
26177 BAD_CAST(xmlChar *) normValue);
26178 xmlFree(normValue);
26179 } else
26180 textChild = xmlNewDocText(inode->node->doc,
26181 inode->decl->value);
26182 if (textChild == NULL((void*)0)) {
26183 VERROR_INT("xmlSchemaValidatorPopElem",xmlSchemaInternalErr((xmlSchemaAbstractCtxtPtr) vctxt, "xmlSchemaValidatorPopElem"
, "calling xmlNewDocText()");
26184 "calling xmlNewDocText()")xmlSchemaInternalErr((xmlSchemaAbstractCtxtPtr) vctxt, "xmlSchemaValidatorPopElem"
, "calling xmlNewDocText()");
;
26185 goto internal_error;
26186 } else
26187 xmlAddChild(inode->node, textChild);
26188 }
26189
26190 } else if (! INODE_NILLED(inode)(inode->flags & 1<<2)) {
26191 /*
26192 * 5.2.1 The element information item must be `valid` with respect
26193 * to the `actual type definition` as defined by Element Locally
26194 * Valid (Type) ($3.3.4).
26195 */
26196 if (WXS_IS_SIMPLE(inode->typeDef)((inode->typeDef->type == XML_SCHEMA_TYPE_SIMPLE) || ((
inode->typeDef->type == XML_SCHEMA_TYPE_BASIC) &&
(inode->typeDef->builtInType != XML_SCHEMAS_ANYTYPE)))
) {
26197 /*
26198 * SPEC (cvc-type) (3.1)
26199 * "If the type definition is a simple type definition, ..."
26200 * (3.1.3) "If clause 3.2 of Element Locally Valid
26201 * (Element) ($3.3.4) did not apply, then the `normalized value`
26202 * must be `valid` with respect to the type definition as defined
26203 * by String Valid ($3.14.4).
26204 */
26205 ret = xmlSchemaVCheckINodeDataType(vctxt,
26206 inode, inode->typeDef, inode->value);
26207 } else if (WXS_HAS_SIMPLE_CONTENT(inode->typeDef)((inode->typeDef->contentType == XML_SCHEMA_CONTENT_SIMPLE
) || (inode->typeDef->contentType == XML_SCHEMA_CONTENT_BASIC
))
) {
26208 /*
26209 * SPEC (cvc-type) (3.2) "If the type definition is a complex type
26210 * definition, then the element information item must be
26211 * `valid` with respect to the type definition as per
26212 * Element Locally Valid (Complex Type) ($3.4.4);"
26213 *
26214 * SPEC (cvc-complex-type) (2.2)
26215 * "If the {content type} is a simple type definition, ...
26216 * the `normalized value` of the element information item is
26217 * `valid` with respect to that simple type definition as
26218 * defined by String Valid ($3.14.4)."
26219 */
26220 ret = xmlSchemaVCheckINodeDataType(vctxt,
26221 inode, inode->typeDef->contentTypeDef, inode->value);
26222 }
26223 if (ret != 0) {
26224 if (ret < 0) {
26225 VERROR_INT("xmlSchemaValidatorPopElem",xmlSchemaInternalErr((xmlSchemaAbstractCtxtPtr) vctxt, "xmlSchemaValidatorPopElem"
, "calling xmlSchemaVCheckCVCSimpleType()");
26226 "calling xmlSchemaVCheckCVCSimpleType()")xmlSchemaInternalErr((xmlSchemaAbstractCtxtPtr) vctxt, "xmlSchemaValidatorPopElem"
, "calling xmlSchemaVCheckCVCSimpleType()");
;
26227 goto internal_error;
26228 }
26229 goto end_elem;
26230 }
26231 /*
26232 * 5.2.2 If there is a fixed {value constraint} and clause 3.2 has
26233 * not applied, all of the following must be true:
26234 */
26235 if ((inode->decl->value != NULL((void*)0)) &&
26236 (inode->decl->flags & XML_SCHEMAS_ELEM_FIXED1 << 3)) {
26237
26238 /*
26239 * TODO: We will need a computed value, when comparison is
26240 * done on computed values.
26241 */
26242 /*
26243 * 5.2.2.1 The element information item must have no element
26244 * information item [children].
26245 */
26246 if (inode->flags &
26247 XML_SCHEMA_ELEM_INFO_HAS_ELEM_CONTENT1<<7) {
26248 ret = XML_SCHEMAV_CVC_ELT_5_2_2_1;
26249 VERROR(ret, NULL,xmlSchemaCustomErr((xmlSchemaAbstractCtxtPtr) vctxt, ret, ((void
*)0), ((void*)0), "The content must not contain element nodes since "
"there is a fixed value constraint", ((void*)0), ((void*)0))
;
26250 "The content must not contain element nodes since "xmlSchemaCustomErr((xmlSchemaAbstractCtxtPtr) vctxt, ret, ((void
*)0), ((void*)0), "The content must not contain element nodes since "
"there is a fixed value constraint", ((void*)0), ((void*)0))
;
26251 "there is a fixed value constraint")xmlSchemaCustomErr((xmlSchemaAbstractCtxtPtr) vctxt, ret, ((void
*)0), ((void*)0), "The content must not contain element nodes since "
"there is a fixed value constraint", ((void*)0), ((void*)0))
;
;
26252 goto end_elem;
26253 } else {
26254 /*
26255 * 5.2.2.2 The appropriate case among the following must
26256 * be true:
26257 */
26258 if (WXS_HAS_MIXED_CONTENT(inode->typeDef)(inode->typeDef->contentType == XML_SCHEMA_CONTENT_MIXED
)
) {
26259 /*
26260 * 5.2.2.2.1 If the {content type} of the `actual type
26261 * definition` is mixed, then the *initial value* of the
26262 * item must match the canonical lexical representation
26263 * of the {value constraint} value.
26264 *
26265 * ... the *initial value* of an element information
26266 * item is the string composed of, in order, the
26267 * [character code] of each character information item in
26268 * the [children] of that element information item.
26269 */
26270 if (! xmlStrEqual(inode->value, inode->decl->value)){
26271 /*
26272 * VAL TODO: Report invalid & expected values as well.
26273 * VAL TODO: Implement the canonical stuff.
26274 */
26275 ret = XML_SCHEMAV_CVC_ELT_5_2_2_2_1;
26276 xmlSchemaCustomErr(ACTXT_CAST(xmlSchemaAbstractCtxtPtr) vctxt,
26277 ret, NULL((void*)0), NULL((void*)0),
26278 "The initial value '%s' does not match the fixed "
26279 "value constraint '%s'",
26280 inode->value, inode->decl->value);
26281 goto end_elem;
26282 }
26283 } else if (WXS_HAS_SIMPLE_CONTENT(inode->typeDef)((inode->typeDef->contentType == XML_SCHEMA_CONTENT_SIMPLE
) || (inode->typeDef->contentType == XML_SCHEMA_CONTENT_BASIC
))
) {
26284 /*
26285 * 5.2.2.2.2 If the {content type} of the `actual type
26286 * definition` is a simple type definition, then the
26287 * *actual value* of the item must match the canonical
26288 * lexical representation of the {value constraint} value.
26289 */
26290 /*
26291 * VAL TODO: *actual value* is the normalized value, impl.
26292 * this.
26293 * VAL TODO: Report invalid & expected values as well.
26294 * VAL TODO: Implement a comparison with the computed values.
26295 */
26296 if (! xmlStrEqual(inode->value,
26297 inode->decl->value)) {
26298 ret = XML_SCHEMAV_CVC_ELT_5_2_2_2_2;
26299 xmlSchemaCustomErr(ACTXT_CAST(xmlSchemaAbstractCtxtPtr) vctxt,
26300 ret, NULL((void*)0), NULL((void*)0),
26301 "The actual value '%s' does not match the fixed "
26302 "value constraint '%s'",
26303 inode->value,
26304 inode->decl->value);
26305 goto end_elem;
26306 }
26307 }
26308 }
26309 }
26310 }
26311
26312end_elem:
26313 if (vctxt->depth < 0) {
26314 /* TODO: raise error? */
26315 return (0);
26316 }
26317 if (vctxt->depth == vctxt->skipDepth)
26318 vctxt->skipDepth = -1;
26319 /*
26320 * Evaluate the history of XPath state objects.
26321 */
26322 if (inode->appliedXPath &&
26323 (xmlSchemaXPathProcessHistory(vctxt, vctxt->depth) == -1))
26324 goto internal_error;
26325 /*
26326 * MAYBE TODO:
26327 * SPEC (6) "The element information item must be `valid` with
26328 * respect to each of the {identity-constraint definitions} as per
26329 * Identity-constraint Satisfied ($3.11.4)."
26330 */
26331 /*
26332 * PSVI TODO: If we expose IDC node-tables via PSVI then the tables
26333 * need to be built in any case.
26334 * We will currently build IDC node-tables and bubble them only if
26335 * keyrefs do exist.
26336 */
26337
26338 /*
26339 * Add the current IDC target-nodes to the IDC node-tables.
26340 */
26341 if ((inode->idcMatchers != NULL((void*)0)) &&
26342 (vctxt->hasKeyrefs || vctxt->createIDCNodeTables))
26343 {
26344 if (xmlSchemaIDCFillNodeTables(vctxt, inode) == -1)
26345 goto internal_error;
26346 }
26347 /*
26348 * Validate IDC keyrefs.
26349 */
26350 if (vctxt->inode->hasKeyrefs)
26351 if (xmlSchemaCheckCVCIDCKeyRef(vctxt) == -1)
26352 goto internal_error;
26353 /*
26354 * Merge/free the IDC table.
26355 */
26356 if (inode->idcTable != NULL((void*)0)) {
26357 if ((vctxt->depth > 0) &&
26358 (vctxt->hasKeyrefs || vctxt->createIDCNodeTables))
26359 {
26360 /*
26361 * Merge the IDC node table with the table of the parent node.
26362 */
26363 if (xmlSchemaBubbleIDCNodeTables(vctxt) == -1)
26364 goto internal_error;
26365 }
26366 }
26367 /*
26368 * Clear the current ielem.
26369 * VAL TODO: Don't free the PSVI IDC tables if they are
26370 * requested for the PSVI.
26371 */
26372 xmlSchemaClearElemInfo(vctxt, inode);
26373 /*
26374 * Skip further processing if we are on the validation root.
26375 */
26376 if (vctxt->depth == 0) {
26377 vctxt->depth--;
26378 vctxt->inode = NULL((void*)0);
26379 return (0);
26380 }
26381 /*
26382 * Reset the keyrefDepth if needed.
26383 */
26384 if (vctxt->aidcs != NULL((void*)0)) {
26385 xmlSchemaIDCAugPtr aidc = vctxt->aidcs;
26386 do {
26387 if (aidc->keyrefDepth == vctxt->depth) {
26388 /*
26389 * A 'keyrefDepth' of a key/unique IDC matches the current
26390 * depth, this means that we are leaving the scope of the
26391 * top-most keyref IDC which refers to this IDC.
26392 */
26393 aidc->keyrefDepth = -1;
26394 }
26395 aidc = aidc->next;
26396 } while (aidc != NULL((void*)0));
26397 }
26398 vctxt->depth--;
26399 vctxt->inode = vctxt->elemInfos[vctxt->depth];
26400 /*
26401 * VAL TODO: 7 If the element information item is the `validation root`, it must be
26402 * `valid` per Validation Root Valid (ID/IDREF) ($3.3.4).
26403 */
26404 return (ret);
26405
26406internal_error:
26407 vctxt->err = -1;
26408 return (-1);
26409}
26410
26411/*
26412* 3.4.4 Complex Type Definition Validation Rules
26413* Validation Rule: Element Locally Valid (Complex Type) (cvc-complex-type)
26414*/
26415static int
26416xmlSchemaValidateChildElem(xmlSchemaValidCtxtPtr vctxt)
26417{
26418 xmlSchemaNodeInfoPtr pielem;
26419 xmlSchemaTypePtr ptype;
26420 int ret = 0;
26421
26422 if (vctxt->depth <= 0) {
26423 VERROR_INT("xmlSchemaValidateChildElem",xmlSchemaInternalErr((xmlSchemaAbstractCtxtPtr) vctxt, "xmlSchemaValidateChildElem"
, "not intended for the validation root");
26424 "not intended for the validation root")xmlSchemaInternalErr((xmlSchemaAbstractCtxtPtr) vctxt, "xmlSchemaValidateChildElem"
, "not intended for the validation root");
;
26425 return (-1);
26426 }
26427 pielem = vctxt->elemInfos[vctxt->depth -1];
26428 if (pielem->flags & XML_SCHEMA_ELEM_INFO_EMPTY1<<5)
26429 pielem->flags ^= XML_SCHEMA_ELEM_INFO_EMPTY1<<5;
26430 /*
26431 * Handle 'nilled' elements.
26432 */
26433 if (INODE_NILLED(pielem)(pielem->flags & 1<<2)) {
26434 /*
26435 * SPEC (cvc-elt) (3.3.4) : (3.2.1)
26436 */
26437 ACTIVATE_PARENT_ELEMvctxt->inode = vctxt->elemInfos[vctxt->depth -1];;
26438 ret = XML_SCHEMAV_CVC_ELT_3_2_1;
26439 VERROR(ret, NULL,xmlSchemaCustomErr((xmlSchemaAbstractCtxtPtr) vctxt, ret, ((void
*)0), ((void*)0), "Neither character nor element content is allowed, "
"because the element was 'nilled'", ((void*)0), ((void*)0));
26440 "Neither character nor element content is allowed, "xmlSchemaCustomErr((xmlSchemaAbstractCtxtPtr) vctxt, ret, ((void
*)0), ((void*)0), "Neither character nor element content is allowed, "
"because the element was 'nilled'", ((void*)0), ((void*)0));
26441 "because the element was 'nilled'")xmlSchemaCustomErr((xmlSchemaAbstractCtxtPtr) vctxt, ret, ((void
*)0), ((void*)0), "Neither character nor element content is allowed, "
"because the element was 'nilled'", ((void*)0), ((void*)0));
;
26442 ACTIVATE_ELEMvctxt->inode = vctxt->elemInfos[vctxt->depth];;
26443 goto unexpected_elem;
26444 }
26445
26446 ptype = pielem->typeDef;
26447
26448 if (ptype->builtInType == XML_SCHEMAS_ANYTYPE) {
26449 /*
26450 * Workaround for "anyType": we have currently no content model
26451 * assigned for "anyType", so handle it explicitly.
26452 * "anyType" has an unbounded, lax "any" wildcard.
26453 */
26454 vctxt->inode->decl = xmlSchemaGetElem(vctxt->schema,
26455 vctxt->inode->localName,
26456 vctxt->inode->nsName);
26457
26458 if (vctxt->inode->decl == NULL((void*)0)) {
26459 xmlSchemaAttrInfoPtr iattr;
26460 /*
26461 * Process "xsi:type".
26462 * SPEC (cvc-assess-elt) (1.2.1.2.1) - (1.2.1.2.3)
26463 */
26464 iattr = xmlSchemaGetMetaAttrInfo(vctxt,
26465 XML_SCHEMA_ATTR_INFO_META_XSI_TYPE1);
26466 if (iattr != NULL((void*)0)) {
26467 ret = xmlSchemaProcessXSIType(vctxt, iattr,
26468 &(vctxt->inode->typeDef), NULL((void*)0));
26469 if (ret != 0) {
26470 if (ret == -1) {
26471 VERROR_INT("xmlSchemaValidateChildElem",xmlSchemaInternalErr((xmlSchemaAbstractCtxtPtr) vctxt, "xmlSchemaValidateChildElem"
, "calling xmlSchemaProcessXSIType() to " "process the attribute 'xsi:nil'"
);
26472 "calling xmlSchemaProcessXSIType() to "xmlSchemaInternalErr((xmlSchemaAbstractCtxtPtr) vctxt, "xmlSchemaValidateChildElem"
, "calling xmlSchemaProcessXSIType() to " "process the attribute 'xsi:nil'"
);
26473 "process the attribute 'xsi:nil'")xmlSchemaInternalErr((xmlSchemaAbstractCtxtPtr) vctxt, "xmlSchemaValidateChildElem"
, "calling xmlSchemaProcessXSIType() to " "process the attribute 'xsi:nil'"
);
;
26474 return (-1);
26475 }
26476 return (ret);
26477 }
26478 } else {
26479 /*
26480 * Fallback to "anyType".
26481 *
26482 * SPEC (cvc-assess-elt)
26483 * "If the item cannot be `strictly assessed`, [...]
26484 * an element information item's schema validity may be laxly
26485 * assessed if its `context-determined declaration` is not
26486 * skip by `validating` with respect to the `ur-type
26487 * definition` as per Element Locally Valid (Type) ($3.3.4)."
26488 */
26489 vctxt->inode->typeDef =
26490 xmlSchemaGetBuiltInType(XML_SCHEMAS_ANYTYPE);
26491 }
26492 }
26493 return (0);
26494 }
26495
26496 switch (ptype->contentType) {
26497 case XML_SCHEMA_CONTENT_EMPTY:
26498 /*
26499 * SPEC (2.1) "If the {content type} is empty, then the
26500 * element information item has no character or element
26501 * information item [children]."
26502 */
26503 ACTIVATE_PARENT_ELEMvctxt->inode = vctxt->elemInfos[vctxt->depth -1];
26504 ret = XML_SCHEMAV_CVC_COMPLEX_TYPE_2_1;
26505 VERROR(ret, NULL,xmlSchemaCustomErr((xmlSchemaAbstractCtxtPtr) vctxt, ret, ((void
*)0), ((void*)0), "Element content is not allowed, " "because the content type is empty"
, ((void*)0), ((void*)0));
26506 "Element content is not allowed, "xmlSchemaCustomErr((xmlSchemaAbstractCtxtPtr) vctxt, ret, ((void
*)0), ((void*)0), "Element content is not allowed, " "because the content type is empty"
, ((void*)0), ((void*)0));
26507 "because the content type is empty")xmlSchemaCustomErr((xmlSchemaAbstractCtxtPtr) vctxt, ret, ((void
*)0), ((void*)0), "Element content is not allowed, " "because the content type is empty"
, ((void*)0), ((void*)0));
;
26508 ACTIVATE_ELEMvctxt->inode = vctxt->elemInfos[vctxt->depth];
26509 goto unexpected_elem;
26510 break;
26511
26512 case XML_SCHEMA_CONTENT_MIXED:
26513 case XML_SCHEMA_CONTENT_ELEMENTS: {
26514 xmlRegExecCtxtPtr regexCtxt;
26515 xmlChar *values[10];
26516 int terminal, nbval = 10, nbneg;
26517
26518 /* VAL TODO: Optimized "anyType" validation.*/
26519
26520 if (ptype->contModel == NULL((void*)0)) {
26521 VERROR_INT("xmlSchemaValidateChildElem",xmlSchemaInternalErr((xmlSchemaAbstractCtxtPtr) vctxt, "xmlSchemaValidateChildElem"
, "type has elem content but no content model");
26522 "type has elem content but no content model")xmlSchemaInternalErr((xmlSchemaAbstractCtxtPtr) vctxt, "xmlSchemaValidateChildElem"
, "type has elem content but no content model");
;
26523 return (-1);
26524 }
26525 /*
26526 * Safety belt for evaluation if the cont. model was already
26527 * examined to be invalid.
26528 */
26529 if (pielem->flags & XML_SCHEMA_ELEM_INFO_ERR_BAD_CONTENT1<<8) {
26530 VERROR_INT("xmlSchemaValidateChildElem",xmlSchemaInternalErr((xmlSchemaAbstractCtxtPtr) vctxt, "xmlSchemaValidateChildElem"
, "validating elem, but elem content is already invalid");
26531 "validating elem, but elem content is already invalid")xmlSchemaInternalErr((xmlSchemaAbstractCtxtPtr) vctxt, "xmlSchemaValidateChildElem"
, "validating elem, but elem content is already invalid");
;
26532 return (-1);
26533 }
26534
26535 regexCtxt = pielem->regexCtxt;
26536 if (regexCtxt == NULL((void*)0)) {
26537 /*
26538 * Create the regex context.
26539 */
26540 regexCtxt = xmlRegNewExecCtxt(ptype->contModel,
26541 xmlSchemaVContentModelCallback, vctxt);
26542 if (regexCtxt == NULL((void*)0)) {
26543 VERROR_INT("xmlSchemaValidateChildElem",xmlSchemaInternalErr((xmlSchemaAbstractCtxtPtr) vctxt, "xmlSchemaValidateChildElem"
, "failed to create a regex context");
26544 "failed to create a regex context")xmlSchemaInternalErr((xmlSchemaAbstractCtxtPtr) vctxt, "xmlSchemaValidateChildElem"
, "failed to create a regex context");
;
26545 return (-1);
26546 }
26547 pielem->regexCtxt = regexCtxt;
26548 }
26549
26550 /*
26551 * SPEC (2.4) "If the {content type} is element-only or mixed,
26552 * then the sequence of the element information item's
26553 * element information item [children], if any, taken in
26554 * order, is `valid` with respect to the {content type}'s
26555 * particle, as defined in Element Sequence Locally Valid
26556 * (Particle) ($3.9.4)."
26557 */
26558 ret = xmlRegExecPushString2(regexCtxt,
26559 vctxt->inode->localName,
26560 vctxt->inode->nsName,
26561 vctxt->inode);
26562 if (vctxt->err == XML_SCHEMAV_INTERNAL) {
26563 VERROR_INT("xmlSchemaValidateChildElem",xmlSchemaInternalErr((xmlSchemaAbstractCtxtPtr) vctxt, "xmlSchemaValidateChildElem"
, "calling xmlRegExecPushString2()");
26564 "calling xmlRegExecPushString2()")xmlSchemaInternalErr((xmlSchemaAbstractCtxtPtr) vctxt, "xmlSchemaValidateChildElem"
, "calling xmlRegExecPushString2()");
;
26565 return (-1);
26566 }
26567 if (ret < 0) {
26568 xmlRegExecErrInfo(regexCtxt, NULL((void*)0), &nbval, &nbneg,
26569 &values[0], &terminal);
26570 xmlSchemaComplexTypeErr(ACTXT_CAST(xmlSchemaAbstractCtxtPtr) vctxt,
26571 XML_SCHEMAV_ELEMENT_CONTENT, NULL((void*)0),NULL((void*)0),
26572 "This element is not expected",
26573 nbval, nbneg, values);
26574 ret = vctxt->err;
26575 goto unexpected_elem;
26576 } else
26577 ret = 0;
26578 }
26579 break;
26580 case XML_SCHEMA_CONTENT_SIMPLE:
26581 case XML_SCHEMA_CONTENT_BASIC:
26582 ACTIVATE_PARENT_ELEMvctxt->inode = vctxt->elemInfos[vctxt->depth -1];
26583 if (WXS_IS_COMPLEX(ptype)(((ptype)->type == XML_SCHEMA_TYPE_COMPLEX) || ((ptype)->
builtInType == XML_SCHEMAS_ANYTYPE))
) {
26584 /*
26585 * SPEC (cvc-complex-type) (2.2)
26586 * "If the {content type} is a simple type definition, then
26587 * the element information item has no element information
26588 * item [children], ..."
26589 */
26590 ret = XML_SCHEMAV_CVC_COMPLEX_TYPE_2_2;
26591 VERROR(ret, NULL, "Element content is not allowed, "xmlSchemaCustomErr((xmlSchemaAbstractCtxtPtr) vctxt, ret, ((void
*)0), ((void*)0), "Element content is not allowed, " "because the content type is a simple type definition"
, ((void*)0), ((void*)0));
26592 "because the content type is a simple type definition")xmlSchemaCustomErr((xmlSchemaAbstractCtxtPtr) vctxt, ret, ((void
*)0), ((void*)0), "Element content is not allowed, " "because the content type is a simple type definition"
, ((void*)0), ((void*)0));
;
26593 } else {
26594 /*
26595 * SPEC (cvc-type) (3.1.2) "The element information item must
26596 * have no element information item [children]."
26597 */
26598 ret = XML_SCHEMAV_CVC_TYPE_3_1_2;
26599 VERROR(ret, NULL, "Element content is not allowed, "xmlSchemaCustomErr((xmlSchemaAbstractCtxtPtr) vctxt, ret, ((void
*)0), ((void*)0), "Element content is not allowed, " "because the type definition is simple"
, ((void*)0), ((void*)0));
26600 "because the type definition is simple")xmlSchemaCustomErr((xmlSchemaAbstractCtxtPtr) vctxt, ret, ((void
*)0), ((void*)0), "Element content is not allowed, " "because the type definition is simple"
, ((void*)0), ((void*)0));
;
26601 }
26602 ACTIVATE_ELEMvctxt->inode = vctxt->elemInfos[vctxt->depth];
26603 ret = vctxt->err;
26604 goto unexpected_elem;
26605 break;
26606
26607 default:
26608 break;
26609 }
26610 return (ret);
26611unexpected_elem:
26612 /*
26613 * Pop this element and set the skipDepth to skip
26614 * all further content of the parent element.
26615 */
26616 vctxt->skipDepth = vctxt->depth;
26617 vctxt->inode->flags |= XML_SCHEMA_NODE_INFO_ERR_NOT_EXPECTED1<<9;
26618 pielem->flags |= XML_SCHEMA_ELEM_INFO_ERR_BAD_CONTENT1<<8;
26619 return (ret);
26620}
26621
26622#define XML_SCHEMA_PUSH_TEXT_PERSIST1 1
26623#define XML_SCHEMA_PUSH_TEXT_CREATED2 2
26624#define XML_SCHEMA_PUSH_TEXT_VOLATILE3 3
26625
26626static int
26627xmlSchemaVPushText(xmlSchemaValidCtxtPtr vctxt,
26628 int nodeType, const xmlChar *value, int len,
26629 int mode, int *consumed)
26630{
26631 /*
26632 * Unfortunately we have to duplicate the text sometimes.
26633 * OPTIMIZE: Maybe we could skip it, if:
26634 * 1. content type is simple
26635 * 2. whitespace is "collapse"
26636 * 3. it consists of whitespace only
26637 *
26638 * Process character content.
26639 */
26640 if (consumed != NULL((void*)0))
26641 *consumed = 0;
26642 if (INODE_NILLED(vctxt->inode)(vctxt->inode->flags & 1<<2)) {
26643 /*
26644 * SPEC cvc-elt (3.3.4 - 3.2.1)
26645 * "The element information item must have no character or
26646 * element information item [children]."
26647 */
26648 VERROR(XML_SCHEMAV_CVC_ELT_3_2_1, NULL,xmlSchemaCustomErr((xmlSchemaAbstractCtxtPtr) vctxt, XML_SCHEMAV_CVC_ELT_3_2_1
, ((void*)0), ((void*)0), "Neither character nor element content is allowed "
"because the element is 'nilled'", ((void*)0), ((void*)0));
26649 "Neither character nor element content is allowed "xmlSchemaCustomErr((xmlSchemaAbstractCtxtPtr) vctxt, XML_SCHEMAV_CVC_ELT_3_2_1
, ((void*)0), ((void*)0), "Neither character nor element content is allowed "
"because the element is 'nilled'", ((void*)0), ((void*)0));
26650 "because the element is 'nilled'")xmlSchemaCustomErr((xmlSchemaAbstractCtxtPtr) vctxt, XML_SCHEMAV_CVC_ELT_3_2_1
, ((void*)0), ((void*)0), "Neither character nor element content is allowed "
"because the element is 'nilled'", ((void*)0), ((void*)0));
;
26651 return (vctxt->err);
26652 }
26653 /*
26654 * SPEC (2.1) "If the {content type} is empty, then the
26655 * element information item has no character or element
26656 * information item [children]."
26657 */
26658 if (vctxt->inode->typeDef->contentType ==
26659 XML_SCHEMA_CONTENT_EMPTY) {
26660 VERROR(XML_SCHEMAV_CVC_COMPLEX_TYPE_2_1, NULL,xmlSchemaCustomErr((xmlSchemaAbstractCtxtPtr) vctxt, XML_SCHEMAV_CVC_COMPLEX_TYPE_2_1
, ((void*)0), ((void*)0), "Character content is not allowed, "
"because the content type is empty", ((void*)0), ((void*)0))
;
26661 "Character content is not allowed, "xmlSchemaCustomErr((xmlSchemaAbstractCtxtPtr) vctxt, XML_SCHEMAV_CVC_COMPLEX_TYPE_2_1
, ((void*)0), ((void*)0), "Character content is not allowed, "
"because the content type is empty", ((void*)0), ((void*)0))
;
26662 "because the content type is empty")xmlSchemaCustomErr((xmlSchemaAbstractCtxtPtr) vctxt, XML_SCHEMAV_CVC_COMPLEX_TYPE_2_1
, ((void*)0), ((void*)0), "Character content is not allowed, "
"because the content type is empty", ((void*)0), ((void*)0))
;
;
26663 return (vctxt->err);
26664 }
26665
26666 if (vctxt->inode->typeDef->contentType ==
26667 XML_SCHEMA_CONTENT_ELEMENTS) {
26668 if ((nodeType != XML_TEXT_NODE) ||
26669 (! xmlSchemaIsBlank((xmlChar *) value, len))) {
26670 /*
26671 * SPEC cvc-complex-type (2.3)
26672 * "If the {content type} is element-only, then the
26673 * element information item has no character information
26674 * item [children] other than those whose [character
26675 * code] is defined as a white space in [XML 1.0 (Second
26676 * Edition)]."
26677 */
26678 VERROR(XML_SCHEMAV_CVC_COMPLEX_TYPE_2_3, NULL,xmlSchemaCustomErr((xmlSchemaAbstractCtxtPtr) vctxt, XML_SCHEMAV_CVC_COMPLEX_TYPE_2_3
, ((void*)0), ((void*)0), "Character content other than whitespace is not allowed "
"because the content type is 'element-only'", ((void*)0), ((
void*)0));
26679 "Character content other than whitespace is not allowed "xmlSchemaCustomErr((xmlSchemaAbstractCtxtPtr) vctxt, XML_SCHEMAV_CVC_COMPLEX_TYPE_2_3
, ((void*)0), ((void*)0), "Character content other than whitespace is not allowed "
"because the content type is 'element-only'", ((void*)0), ((
void*)0));
26680 "because the content type is 'element-only'")xmlSchemaCustomErr((xmlSchemaAbstractCtxtPtr) vctxt, XML_SCHEMAV_CVC_COMPLEX_TYPE_2_3
, ((void*)0), ((void*)0), "Character content other than whitespace is not allowed "
"because the content type is 'element-only'", ((void*)0), ((
void*)0));
;
26681 return (vctxt->err);
26682 }
26683 return (0);
26684 }
26685
26686 if ((value == NULL((void*)0)) || (value[0] == 0))
26687 return (0);
26688 /*
26689 * Save the value.
26690 * NOTE that even if the content type is *mixed*, we need the
26691 * *initial value* for default/fixed value constraints.
26692 */
26693 if ((vctxt->inode->typeDef->contentType == XML_SCHEMA_CONTENT_MIXED) &&
26694 ((vctxt->inode->decl == NULL((void*)0)) ||
26695 (vctxt->inode->decl->value == NULL((void*)0))))
26696 return (0);
26697
26698 if (vctxt->inode->value == NULL((void*)0)) {
26699 /*
26700 * Set the value.
26701 */
26702 switch (mode) {
26703 case XML_SCHEMA_PUSH_TEXT_PERSIST1:
26704 /*
26705 * When working on a tree.
26706 */
26707 vctxt->inode->value = value;
26708 break;
26709 case XML_SCHEMA_PUSH_TEXT_CREATED2:
26710 /*
26711 * When working with the reader.
26712 * The value will be freed by the element info.
26713 */
26714 vctxt->inode->value = value;
26715 if (consumed != NULL((void*)0))
26716 *consumed = 1;
26717 vctxt->inode->flags |=
26718 XML_SCHEMA_NODE_INFO_FLAG_OWNED_VALUES1<<1;
26719 break;
26720 case XML_SCHEMA_PUSH_TEXT_VOLATILE3:
26721 /*
26722 * When working with SAX.
26723 * The value will be freed by the element info.
26724 */
26725 if (len != -1)
26726 vctxt->inode->value = BAD_CAST(xmlChar *) xmlStrndup(value, len);
26727 else
26728 vctxt->inode->value = BAD_CAST(xmlChar *) xmlStrdup(value);
26729 vctxt->inode->flags |=
26730 XML_SCHEMA_NODE_INFO_FLAG_OWNED_VALUES1<<1;
26731 break;
26732 default:
26733 break;
26734 }
26735 } else {
26736 if (len < 0)
26737 len = xmlStrlen(value);
26738 /*
26739 * Concat the value.
26740 */
26741 if (vctxt->inode->flags & XML_SCHEMA_NODE_INFO_FLAG_OWNED_VALUES1<<1) {
26742 vctxt->inode->value = BAD_CAST(xmlChar *) xmlStrncat(
26743 (xmlChar *) vctxt->inode->value, value, len);
26744 } else {
26745 vctxt->inode->value =
26746 BAD_CAST(xmlChar *) xmlStrncatNew(vctxt->inode->value, value, len);
26747 vctxt->inode->flags |= XML_SCHEMA_NODE_INFO_FLAG_OWNED_VALUES1<<1;
26748 }
26749 }
26750
26751 return (0);
26752}
26753
26754static int
26755xmlSchemaValidateElem(xmlSchemaValidCtxtPtr vctxt)
26756{
26757 int ret = 0;
26758
26759 if ((vctxt->skipDepth != -1) &&
26760 (vctxt->depth >= vctxt->skipDepth)) {
26761 VERROR_INT("xmlSchemaValidateElem",xmlSchemaInternalErr((xmlSchemaAbstractCtxtPtr) vctxt, "xmlSchemaValidateElem"
, "in skip-state");
26762 "in skip-state")xmlSchemaInternalErr((xmlSchemaAbstractCtxtPtr) vctxt, "xmlSchemaValidateElem"
, "in skip-state");
;
26763 goto internal_error;
26764 }
26765 if (vctxt->xsiAssemble) {
26766 /*
26767 * We will stop validation if there was an error during
26768 * dynamic schema construction.
26769 * Note that we simply set @skipDepth to 0, this could
26770 * mean that a streaming document via SAX would be
26771 * still read to the end but it won't be validated any more.
26772 * TODO: If we are sure how to stop the validation at once
26773 * for all input scenarios, then this should be changed to
26774 * instantly stop the validation.
26775 */
26776 ret = xmlSchemaAssembleByXSI(vctxt);
26777 if (ret != 0) {
26778 if (ret == -1)
26779 goto internal_error;
26780 vctxt->skipDepth = 0;
26781 return(ret);
26782 }
26783 /*
26784 * Augment the IDC definitions for the main schema and all imported ones
26785 * NOTE: main schema is the first in the imported list
26786 */
26787 xmlHashScan(vctxt->schema->schemasImports, xmlSchemaAugmentImportedIDC,
26788 vctxt);
26789 }
26790 if (vctxt->depth > 0) {
26791 /*
26792 * Validate this element against the content model
26793 * of the parent.
26794 */
26795 ret = xmlSchemaValidateChildElem(vctxt);
26796 if (ret != 0) {
26797 if (ret < 0) {
26798 VERROR_INT("xmlSchemaValidateElem",xmlSchemaInternalErr((xmlSchemaAbstractCtxtPtr) vctxt, "xmlSchemaValidateElem"
, "calling xmlSchemaStreamValidateChildElement()");
26799 "calling xmlSchemaStreamValidateChildElement()")xmlSchemaInternalErr((xmlSchemaAbstractCtxtPtr) vctxt, "xmlSchemaValidateElem"
, "calling xmlSchemaStreamValidateChildElement()");
;
26800 goto internal_error;
26801 }
26802 goto exit;
26803 }
26804 if (vctxt->depth == vctxt->skipDepth)
26805 goto exit;
26806 if ((vctxt->inode->decl == NULL((void*)0)) &&
26807 (vctxt->inode->typeDef == NULL((void*)0))) {
26808 VERROR_INT("xmlSchemaValidateElem",xmlSchemaInternalErr((xmlSchemaAbstractCtxtPtr) vctxt, "xmlSchemaValidateElem"
, "the child element was valid but neither the " "declaration nor the type was set"
);
26809 "the child element was valid but neither the "xmlSchemaInternalErr((xmlSchemaAbstractCtxtPtr) vctxt, "xmlSchemaValidateElem"
, "the child element was valid but neither the " "declaration nor the type was set"
);
26810 "declaration nor the type was set")xmlSchemaInternalErr((xmlSchemaAbstractCtxtPtr) vctxt, "xmlSchemaValidateElem"
, "the child element was valid but neither the " "declaration nor the type was set"
);
;
26811 goto internal_error;
26812 }
26813 } else {
26814 /*
26815 * Get the declaration of the validation root.
26816 */
26817 vctxt->inode->decl = xmlSchemaGetElem(vctxt->schema,
26818 vctxt->inode->localName,
26819 vctxt->inode->nsName);
26820 if (vctxt->inode->decl == NULL((void*)0)) {
26821 ret = XML_SCHEMAV_CVC_ELT_1;
26822 VERROR(ret, NULL,xmlSchemaCustomErr((xmlSchemaAbstractCtxtPtr) vctxt, ret, ((void
*)0), ((void*)0), "No matching global declaration available "
"for the validation root", ((void*)0), ((void*)0));
26823 "No matching global declaration available "xmlSchemaCustomErr((xmlSchemaAbstractCtxtPtr) vctxt, ret, ((void
*)0), ((void*)0), "No matching global declaration available "
"for the validation root", ((void*)0), ((void*)0));
26824 "for the validation root")xmlSchemaCustomErr((xmlSchemaAbstractCtxtPtr) vctxt, ret, ((void
*)0), ((void*)0), "No matching global declaration available "
"for the validation root", ((void*)0), ((void*)0));
;
26825 goto exit;
26826 }
26827 }
26828
26829 if (vctxt->inode->decl == NULL((void*)0))
26830 goto type_validation;
26831
26832 if (vctxt->inode->decl->type == XML_SCHEMA_TYPE_ANY) {
26833 int skip;
26834 /*
26835 * Wildcards.
26836 */
26837 ret = xmlSchemaValidateElemWildcard(vctxt, &skip);
26838 if (ret != 0) {
26839 if (ret < 0) {
26840 VERROR_INT("xmlSchemaValidateElem",xmlSchemaInternalErr((xmlSchemaAbstractCtxtPtr) vctxt, "xmlSchemaValidateElem"
, "calling xmlSchemaValidateElemWildcard()");
26841 "calling xmlSchemaValidateElemWildcard()")xmlSchemaInternalErr((xmlSchemaAbstractCtxtPtr) vctxt, "xmlSchemaValidateElem"
, "calling xmlSchemaValidateElemWildcard()");
;
26842 goto internal_error;
26843 }
26844 goto exit;
26845 }
26846 if (skip) {
26847 vctxt->skipDepth = vctxt->depth;
26848 goto exit;
26849 }
26850 /*
26851 * The declaration might be set by the wildcard validation,
26852 * when the processContents is "lax" or "strict".
26853 */
26854 if (vctxt->inode->decl->type != XML_SCHEMA_TYPE_ELEMENT) {
26855 /*
26856 * Clear the "decl" field to not confuse further processing.
26857 */
26858 vctxt->inode->decl = NULL((void*)0);
26859 goto type_validation;
26860 }
26861 }
26862 /*
26863 * Validate against the declaration.
26864 */
26865 ret = xmlSchemaValidateElemDecl(vctxt);
26866 if (ret != 0) {
26867 if (ret < 0) {
26868 VERROR_INT("xmlSchemaValidateElem",xmlSchemaInternalErr((xmlSchemaAbstractCtxtPtr) vctxt, "xmlSchemaValidateElem"
, "calling xmlSchemaValidateElemDecl()");
26869 "calling xmlSchemaValidateElemDecl()")xmlSchemaInternalErr((xmlSchemaAbstractCtxtPtr) vctxt, "xmlSchemaValidateElem"
, "calling xmlSchemaValidateElemDecl()");
;
26870 goto internal_error;
26871 }
26872 goto exit;
26873 }
26874 /*
26875 * Validate against the type definition.
26876 */
26877type_validation:
26878
26879 if (vctxt->inode->typeDef == NULL((void*)0)) {
26880 vctxt->inode->flags |= XML_SCHEMA_NODE_INFO_ERR_BAD_TYPE1<<10;
26881 ret = XML_SCHEMAV_CVC_TYPE_1;
26882 VERROR(ret, NULL,xmlSchemaCustomErr((xmlSchemaAbstractCtxtPtr) vctxt, ret, ((void
*)0), ((void*)0), "The type definition is absent", ((void*)0)
, ((void*)0));
26883 "The type definition is absent")xmlSchemaCustomErr((xmlSchemaAbstractCtxtPtr) vctxt, ret, ((void
*)0), ((void*)0), "The type definition is absent", ((void*)0)
, ((void*)0));
;
26884 goto exit;
26885 }
26886 if (vctxt->inode->typeDef->flags & XML_SCHEMAS_TYPE_ABSTRACT1 << 20) {
26887 vctxt->inode->flags |= XML_SCHEMA_NODE_INFO_ERR_BAD_TYPE1<<10;
26888 ret = XML_SCHEMAV_CVC_TYPE_2;
26889 VERROR(ret, NULL,xmlSchemaCustomErr((xmlSchemaAbstractCtxtPtr) vctxt, ret, ((void
*)0), ((void*)0), "The type definition is abstract", ((void*)
0), ((void*)0));
26890 "The type definition is abstract")xmlSchemaCustomErr((xmlSchemaAbstractCtxtPtr) vctxt, ret, ((void
*)0), ((void*)0), "The type definition is abstract", ((void*)
0), ((void*)0));
;
26891 goto exit;
26892 }
26893 /*
26894 * Evaluate IDCs. Do it here, since new IDC matchers are registered
26895 * during validation against the declaration. This must be done
26896 * _before_ attribute validation.
26897 */
26898 if (vctxt->xpathStates != NULL((void*)0)) {
26899 ret = xmlSchemaXPathEvaluate(vctxt, XML_ELEMENT_NODE);
26900 vctxt->inode->appliedXPath = 1;
26901 if (ret == -1) {
26902 VERROR_INT("xmlSchemaValidateElem",xmlSchemaInternalErr((xmlSchemaAbstractCtxtPtr) vctxt, "xmlSchemaValidateElem"
, "calling xmlSchemaXPathEvaluate()");
26903 "calling xmlSchemaXPathEvaluate()")xmlSchemaInternalErr((xmlSchemaAbstractCtxtPtr) vctxt, "xmlSchemaValidateElem"
, "calling xmlSchemaXPathEvaluate()");
;
26904 goto internal_error;
26905 }
26906 }
26907 /*
26908 * Validate attributes.
26909 */
26910 if (WXS_IS_COMPLEX(vctxt->inode->typeDef)(((vctxt->inode->typeDef)->type == XML_SCHEMA_TYPE_COMPLEX
) || ((vctxt->inode->typeDef)->builtInType == XML_SCHEMAS_ANYTYPE
))
) {
26911 if ((vctxt->nbAttrInfos != 0) ||
26912 (vctxt->inode->typeDef->attrUses != NULL((void*)0))) {
26913
26914 ret = xmlSchemaVAttributesComplex(vctxt);
26915 }
26916 } else if (vctxt->nbAttrInfos != 0) {
26917
26918 ret = xmlSchemaVAttributesSimple(vctxt);
26919 }
26920 /*
26921 * Clear registered attributes.
26922 */
26923 if (vctxt->nbAttrInfos != 0)
26924 xmlSchemaClearAttrInfos(vctxt);
26925 if (ret == -1) {
26926 VERROR_INT("xmlSchemaValidateElem",xmlSchemaInternalErr((xmlSchemaAbstractCtxtPtr) vctxt, "xmlSchemaValidateElem"
, "calling attributes validation");
26927 "calling attributes validation")xmlSchemaInternalErr((xmlSchemaAbstractCtxtPtr) vctxt, "xmlSchemaValidateElem"
, "calling attributes validation");
;
26928 goto internal_error;
26929 }
26930 /*
26931 * Don't return an error if attributes are invalid on purpose.
26932 */
26933 ret = 0;
26934
26935exit:
26936 if (ret != 0)
26937 vctxt->skipDepth = vctxt->depth;
26938 return (ret);
26939internal_error:
26940 return (-1);
26941}
26942
26943#ifdef XML_SCHEMA_READER_ENABLED
26944static int
26945xmlSchemaVReaderWalk(xmlSchemaValidCtxtPtr vctxt)
26946{
26947 const int WHTSP = 13, SIGN_WHTSP = 14, END_ELEM = 15;
26948 int depth, nodeType, ret = 0, consumed;
26949 xmlSchemaNodeInfoPtr ielem;
26950
26951 vctxt->depth = -1;
26952 ret = xmlTextReaderRead(vctxt->reader);
26953 /*
26954 * Move to the document element.
26955 */
26956 while (ret == 1) {
26957 nodeType = xmlTextReaderNodeType(vctxt->reader);
26958 if (nodeType == XML_ELEMENT_NODE)
26959 goto root_found;
26960 ret = xmlTextReaderRead(vctxt->reader);
26961 }
26962 goto exit;
26963
26964root_found:
26965
26966 do {
26967 depth = xmlTextReaderDepth(vctxt->reader);
26968 nodeType = xmlTextReaderNodeType(vctxt->reader);
26969
26970 if (nodeType == XML_ELEMENT_NODE) {
26971
26972 vctxt->depth++;
26973 if (xmlSchemaValidatorPushElem(vctxt) == -1) {
26974 VERROR_INT("xmlSchemaVReaderWalk",xmlSchemaInternalErr((xmlSchemaAbstractCtxtPtr) vctxt, "xmlSchemaVReaderWalk"
, "calling xmlSchemaValidatorPushElem()");
26975 "calling xmlSchemaValidatorPushElem()")xmlSchemaInternalErr((xmlSchemaAbstractCtxtPtr) vctxt, "xmlSchemaVReaderWalk"
, "calling xmlSchemaValidatorPushElem()");
;
26976 goto internal_error;
26977 }
26978 ielem = vctxt->inode;
26979 ielem->localName = xmlTextReaderLocalName(vctxt->reader);
26980 ielem->nsName = xmlTextReaderNamespaceUri(vctxt->reader);
26981 ielem->flags |= XML_SCHEMA_NODE_INFO_FLAG_OWNED_NAMES1<<0;
26982 /*
26983 * Is the element empty?
26984 */
26985 ret = xmlTextReaderIsEmptyElement(vctxt->reader);
26986 if (ret == -1) {
26987 VERROR_INT("xmlSchemaVReaderWalk",xmlSchemaInternalErr((xmlSchemaAbstractCtxtPtr) vctxt, "xmlSchemaVReaderWalk"
, "calling xmlTextReaderIsEmptyElement()");
26988 "calling xmlTextReaderIsEmptyElement()")xmlSchemaInternalErr((xmlSchemaAbstractCtxtPtr) vctxt, "xmlSchemaVReaderWalk"
, "calling xmlTextReaderIsEmptyElement()");
;
26989 goto internal_error;
26990 }
26991 if (ret) {
26992 ielem->flags |= XML_SCHEMA_ELEM_INFO_EMPTY1<<5;
26993 }
26994 /*
26995 * Register attributes.
26996 */
26997 vctxt->nbAttrInfos = 0;
26998 ret = xmlTextReaderMoveToFirstAttribute(vctxt->reader);
26999 if (ret == -1) {
27000 VERROR_INT("xmlSchemaVReaderWalk",xmlSchemaInternalErr((xmlSchemaAbstractCtxtPtr) vctxt, "xmlSchemaVReaderWalk"
, "calling xmlTextReaderMoveToFirstAttribute()");
27001 "calling xmlTextReaderMoveToFirstAttribute()")xmlSchemaInternalErr((xmlSchemaAbstractCtxtPtr) vctxt, "xmlSchemaVReaderWalk"
, "calling xmlTextReaderMoveToFirstAttribute()");
;
27002 goto internal_error;
27003 }
27004 if (ret == 1) {
27005 do {
27006 /*
27007 * VAL TODO: How do we know that the reader works on a
27008 * node tree, to be able to pass a node here?
27009 */
27010 if (xmlSchemaValidatorPushAttribute(vctxt, NULL((void*)0),
27011 (const xmlChar *) xmlTextReaderLocalName(vctxt->reader),
27012 xmlTextReaderNamespaceUri(vctxt->reader), 1,
27013 xmlTextReaderValue(vctxt->reader), 1) == -1) {
27014
27015 VERROR_INT("xmlSchemaVReaderWalk",xmlSchemaInternalErr((xmlSchemaAbstractCtxtPtr) vctxt, "xmlSchemaVReaderWalk"
, "calling xmlSchemaValidatorPushAttribute()");
27016 "calling xmlSchemaValidatorPushAttribute()")xmlSchemaInternalErr((xmlSchemaAbstractCtxtPtr) vctxt, "xmlSchemaVReaderWalk"
, "calling xmlSchemaValidatorPushAttribute()");
;
27017 goto internal_error;
27018 }
27019 ret = xmlTextReaderMoveToNextAttribute(vctxt->reader);
27020 if (ret == -1) {
27021 VERROR_INT("xmlSchemaVReaderWalk",xmlSchemaInternalErr((xmlSchemaAbstractCtxtPtr) vctxt, "xmlSchemaVReaderWalk"
, "calling xmlTextReaderMoveToFirstAttribute()");
27022 "calling xmlTextReaderMoveToFirstAttribute()")xmlSchemaInternalErr((xmlSchemaAbstractCtxtPtr) vctxt, "xmlSchemaVReaderWalk"
, "calling xmlTextReaderMoveToFirstAttribute()");
;
27023 goto internal_error;
27024 }
27025 } while (ret == 1);
27026 /*
27027 * Back to element position.
27028 */
27029 ret = xmlTextReaderMoveToElement(vctxt->reader);
27030 if (ret == -1) {
27031 VERROR_INT("xmlSchemaVReaderWalk",xmlSchemaInternalErr((xmlSchemaAbstractCtxtPtr) vctxt, "xmlSchemaVReaderWalk"
, "calling xmlTextReaderMoveToElement()");
27032 "calling xmlTextReaderMoveToElement()")xmlSchemaInternalErr((xmlSchemaAbstractCtxtPtr) vctxt, "xmlSchemaVReaderWalk"
, "calling xmlTextReaderMoveToElement()");
;
27033 goto internal_error;
27034 }
27035 }
27036 /*
27037 * Validate the element.
27038 */
27039 ret= xmlSchemaValidateElem(vctxt);
27040 if (ret != 0) {
27041 if (ret == -1) {
27042 VERROR_INT("xmlSchemaVReaderWalk",xmlSchemaInternalErr((xmlSchemaAbstractCtxtPtr) vctxt, "xmlSchemaVReaderWalk"
, "calling xmlSchemaValidateElem()");
27043 "calling xmlSchemaValidateElem()")xmlSchemaInternalErr((xmlSchemaAbstractCtxtPtr) vctxt, "xmlSchemaVReaderWalk"
, "calling xmlSchemaValidateElem()");
;
27044 goto internal_error;
27045 }
27046 goto exit;
27047 }
27048 if (vctxt->depth == vctxt->skipDepth) {
27049 int curDepth;
27050 /*
27051 * Skip all content.
27052 */
27053 if ((ielem->flags & XML_SCHEMA_ELEM_INFO_EMPTY1<<5) == 0) {
27054 ret = xmlTextReaderRead(vctxt->reader);
27055 curDepth = xmlTextReaderDepth(vctxt->reader);
27056 while ((ret == 1) && (curDepth != depth)) {
27057 ret = xmlTextReaderRead(vctxt->reader);
27058 curDepth = xmlTextReaderDepth(vctxt->reader);
27059 }
27060 if (ret < 0) {
27061 /*
27062 * VAL TODO: A reader error occurred; what to do here?
27063 */
27064 ret = 1;
27065 goto exit;
27066 }
27067 }
27068 goto leave_elem;
27069 }
27070 /*
27071 * READER VAL TODO: Is an END_ELEM really never called
27072 * if the elem is empty?
27073 */
27074 if (ielem->flags & XML_SCHEMA_ELEM_INFO_EMPTY1<<5)
27075 goto leave_elem;
27076 } else if (nodeType == END_ELEM) {
27077 /*
27078 * Process END of element.
27079 */
27080leave_elem:
27081 ret = xmlSchemaValidatorPopElem(vctxt);
27082 if (ret != 0) {
27083 if (ret < 0) {
27084 VERROR_INT("xmlSchemaVReaderWalk",xmlSchemaInternalErr((xmlSchemaAbstractCtxtPtr) vctxt, "xmlSchemaVReaderWalk"
, "calling xmlSchemaValidatorPopElem()");
27085 "calling xmlSchemaValidatorPopElem()")xmlSchemaInternalErr((xmlSchemaAbstractCtxtPtr) vctxt, "xmlSchemaVReaderWalk"
, "calling xmlSchemaValidatorPopElem()");
;
27086 goto internal_error;
27087 }
27088 goto exit;
27089 }
27090 if (vctxt->depth >= 0)
27091 ielem = vctxt->inode;
27092 else
27093 ielem = NULL((void*)0);
27094 } else if ((nodeType == XML_TEXT_NODE) ||
27095 (nodeType == XML_CDATA_SECTION_NODE) ||
27096 (nodeType == WHTSP) ||
27097 (nodeType == SIGN_WHTSP)) {
27098 /*
27099 * Process character content.
27100 */
27101 xmlChar *value;
27102
27103 if ((nodeType == WHTSP) || (nodeType == SIGN_WHTSP))
27104 nodeType = XML_TEXT_NODE;
27105
27106 value = xmlTextReaderValue(vctxt->reader);
27107 ret = xmlSchemaVPushText(vctxt, nodeType, BAD_CAST(xmlChar *) value,
27108 -1, XML_SCHEMA_PUSH_TEXT_CREATED2, &consumed);
27109 if (! consumed)
27110 xmlFree(value);
27111 if (ret == -1) {
27112 VERROR_INT("xmlSchemaVReaderWalk",xmlSchemaInternalErr((xmlSchemaAbstractCtxtPtr) vctxt, "xmlSchemaVReaderWalk"
, "calling xmlSchemaVPushText()");
27113 "calling xmlSchemaVPushText()")xmlSchemaInternalErr((xmlSchemaAbstractCtxtPtr) vctxt, "xmlSchemaVReaderWalk"
, "calling xmlSchemaVPushText()");
;
27114 goto internal_error;
27115 }
27116 } else if ((nodeType == XML_ENTITY_NODE) ||
27117 (nodeType == XML_ENTITY_REF_NODE)) {
27118 /*
27119 * VAL TODO: What to do with entities?
27120 */
27121 TODO(*__xmlGenericError())((*__xmlGenericErrorContext()), "Unimplemented block at %s:%d\n"
, "xmlschemas.c", 27121);
27122 }
27123 /*
27124 * Read next node.
27125 */
27126 ret = xmlTextReaderRead(vctxt->reader);
27127 } while (ret == 1);
27128
27129exit:
27130 return (ret);
27131internal_error:
27132 return (-1);
27133}
27134#endif
27135
27136/************************************************************************
27137 * *
27138 * SAX validation handlers *
27139 * *
27140 ************************************************************************/
27141
27142/*
27143* Process text content.
27144*/
27145static void
27146xmlSchemaSAXHandleText(void *ctx,
27147 const xmlChar * ch,
27148 int len)
27149{
27150 xmlSchemaValidCtxtPtr vctxt = (xmlSchemaValidCtxtPtr) ctx;
27151
27152 if (vctxt->depth < 0)
27153 return;
27154 if ((vctxt->skipDepth != -1) && (vctxt->depth >= vctxt->skipDepth))
27155 return;
27156 if (vctxt->inode->flags & XML_SCHEMA_ELEM_INFO_EMPTY1<<5)
27157 vctxt->inode->flags ^= XML_SCHEMA_ELEM_INFO_EMPTY1<<5;
27158 if (xmlSchemaVPushText(vctxt, XML_TEXT_NODE, ch, len,
27159 XML_SCHEMA_PUSH_TEXT_VOLATILE3, NULL((void*)0)) == -1) {
27160 VERROR_INT("xmlSchemaSAXHandleCDataSection",xmlSchemaInternalErr((xmlSchemaAbstractCtxtPtr) vctxt, "xmlSchemaSAXHandleCDataSection"
, "calling xmlSchemaVPushText()");
27161 "calling xmlSchemaVPushText()")xmlSchemaInternalErr((xmlSchemaAbstractCtxtPtr) vctxt, "xmlSchemaSAXHandleCDataSection"
, "calling xmlSchemaVPushText()");
;
27162 vctxt->err = -1;
27163 xmlStopParser(vctxt->parserCtxt);
27164 }
27165}
27166
27167/*
27168* Process CDATA content.
27169*/
27170static void
27171xmlSchemaSAXHandleCDataSection(void *ctx,
27172 const xmlChar * ch,
27173 int len)
27174{
27175 xmlSchemaValidCtxtPtr vctxt = (xmlSchemaValidCtxtPtr) ctx;
27176
27177 if (vctxt->depth < 0)
27178 return;
27179 if ((vctxt->skipDepth != -1) && (vctxt->depth >= vctxt->skipDepth))
27180 return;
27181 if (vctxt->inode->flags & XML_SCHEMA_ELEM_INFO_EMPTY1<<5)
27182 vctxt->inode->flags ^= XML_SCHEMA_ELEM_INFO_EMPTY1<<5;
27183 if (xmlSchemaVPushText(vctxt, XML_CDATA_SECTION_NODE, ch, len,
27184 XML_SCHEMA_PUSH_TEXT_VOLATILE3, NULL((void*)0)) == -1) {
27185 VERROR_INT("xmlSchemaSAXHandleCDataSection",xmlSchemaInternalErr((xmlSchemaAbstractCtxtPtr) vctxt, "xmlSchemaSAXHandleCDataSection"
, "calling xmlSchemaVPushText()");
27186 "calling xmlSchemaVPushText()")xmlSchemaInternalErr((xmlSchemaAbstractCtxtPtr) vctxt, "xmlSchemaSAXHandleCDataSection"
, "calling xmlSchemaVPushText()");
;
27187 vctxt->err = -1;
27188 xmlStopParser(vctxt->parserCtxt);
27189 }
27190}
27191
27192static void
27193xmlSchemaSAXHandleReference(void *ctx ATTRIBUTE_UNUSED__attribute__((unused)),
27194 const xmlChar * name ATTRIBUTE_UNUSED__attribute__((unused)))
27195{
27196 xmlSchemaValidCtxtPtr vctxt = (xmlSchemaValidCtxtPtr) ctx;
27197
27198 if (vctxt->depth < 0)
27199 return;
27200 if ((vctxt->skipDepth != -1) && (vctxt->depth >= vctxt->skipDepth))
27201 return;
27202 /* SAX VAL TODO: What to do here? */
27203 TODO(*__xmlGenericError())((*__xmlGenericErrorContext()), "Unimplemented block at %s:%d\n"
, "xmlschemas.c", 27203);
27204}
27205
27206static void
27207xmlSchemaSAXHandleStartElementNs(void *ctx,
27208 const xmlChar * localname,
27209 const xmlChar * prefix ATTRIBUTE_UNUSED__attribute__((unused)),
27210 const xmlChar * URI,
27211 int nb_namespaces,
27212 const xmlChar ** namespaces,
27213 int nb_attributes,
27214 int nb_defaulted ATTRIBUTE_UNUSED__attribute__((unused)),
27215 const xmlChar ** attributes)
27216{
27217 xmlSchemaValidCtxtPtr vctxt = (xmlSchemaValidCtxtPtr) ctx;
27218 int ret;
27219 xmlSchemaNodeInfoPtr ielem;
27220 int i, j;
27221
27222 /*
27223 * SAX VAL TODO: What to do with nb_defaulted?
27224 */
27225 /*
27226 * Skip elements if inside a "skip" wildcard or invalid.
27227 */
27228 vctxt->depth++;
27229 if ((vctxt->skipDepth != -1) && (vctxt->depth >= vctxt->skipDepth))
27230 return;
27231 /*
27232 * Push the element.
27233 */
27234 if (xmlSchemaValidatorPushElem(vctxt) == -1) {
27235 VERROR_INT("xmlSchemaSAXHandleStartElementNs",xmlSchemaInternalErr((xmlSchemaAbstractCtxtPtr) vctxt, "xmlSchemaSAXHandleStartElementNs"
, "calling xmlSchemaValidatorPushElem()");
27236 "calling xmlSchemaValidatorPushElem()")xmlSchemaInternalErr((xmlSchemaAbstractCtxtPtr) vctxt, "xmlSchemaSAXHandleStartElementNs"
, "calling xmlSchemaValidatorPushElem()");
;
27237 goto internal_error;
27238 }
27239 ielem = vctxt->inode;
27240 /*
27241 * TODO: Is this OK?
27242 */
27243 ielem->nodeLine = xmlSAX2GetLineNumber(vctxt->parserCtxt);
27244 ielem->localName = localname;
27245 ielem->nsName = URI;
27246 ielem->flags |= XML_SCHEMA_ELEM_INFO_EMPTY1<<5;
27247 /*
27248 * Register namespaces on the elem info.
27249 */
27250 if (nb_namespaces != 0) {
27251 /*
27252 * Although the parser builds its own namespace list,
27253 * we have no access to it, so we'll use an own one.
27254 */
27255 for (i = 0, j = 0; i < nb_namespaces; i++, j += 2) {
27256 /*
27257 * Store prefix and namespace name.
27258 */
27259 if (ielem->nsBindings == NULL((void*)0)) {
27260 ielem->nsBindings =
27261 (const xmlChar **) xmlMalloc(10 *
27262 sizeof(const xmlChar *));
27263 if (ielem->nsBindings == NULL((void*)0)) {
27264 xmlSchemaVErrMemory(vctxt,
27265 "allocating namespace bindings for SAX validation",
27266 NULL((void*)0));
27267 goto internal_error;
27268 }
27269 ielem->nbNsBindings = 0;
27270 ielem->sizeNsBindings = 5;
27271 } else if (ielem->sizeNsBindings <= ielem->nbNsBindings) {
27272 ielem->sizeNsBindings *= 2;
27273 ielem->nsBindings =
27274 (const xmlChar **) xmlRealloc(
27275 (void *) ielem->nsBindings,
27276 ielem->sizeNsBindings * 2 * sizeof(const xmlChar *));
27277 if (ielem->nsBindings == NULL((void*)0)) {
27278 xmlSchemaVErrMemory(vctxt,
27279 "re-allocating namespace bindings for SAX validation",
27280 NULL((void*)0));
27281 goto internal_error;
27282 }
27283 }
27284
27285 ielem->nsBindings[ielem->nbNsBindings * 2] = namespaces[j];
27286 if (namespaces[j+1][0] == 0) {
27287 /*
27288 * Handle xmlns="".
27289 */
27290 ielem->nsBindings[ielem->nbNsBindings * 2 + 1] = NULL((void*)0);
27291 } else
27292 ielem->nsBindings[ielem->nbNsBindings * 2 + 1] =
27293 namespaces[j+1];
27294 ielem->nbNsBindings++;
27295 }
27296 }
27297 /*
27298 * Register attributes.
27299 * SAX VAL TODO: We are not adding namespace declaration
27300 * attributes yet.
27301 */
27302 if (nb_attributes != 0) {
27303 int valueLen, k, l;
27304 xmlChar *value;
27305
27306 for (j = 0, i = 0; i < nb_attributes; i++, j += 5) {
27307 /*
27308 * Duplicate the value, changing any &#38; to a literal ampersand.
27309 *
27310 * libxml2 differs from normal SAX here in that it escapes all ampersands
27311 * as &#38; instead of delivering the raw converted string. Changing the
27312 * behavior at this point would break applications that use this API, so
27313 * we are forced to work around it.
27314 */
27315 valueLen = attributes[j+4] - attributes[j+3];
27316 value = xmlMallocAtomic(valueLen + 1);
27317 if (value == NULL((void*)0)) {
27318 xmlSchemaVErrMemory(vctxt,
27319 "allocating string for decoded attribute",
27320 NULL((void*)0));
27321 goto internal_error;
27322 }
27323 for (k = 0, l = 0; k < valueLen; l++) {
27324 if (k < valueLen - 4 &&
27325 attributes[j+3][k+0] == '&' &&
27326 attributes[j+3][k+1] == '#' &&
27327 attributes[j+3][k+2] == '3' &&
27328 attributes[j+3][k+3] == '8' &&
27329 attributes[j+3][k+4] == ';') {
27330 value[l] = '&';
27331 k += 5;
27332 } else {
27333 value[l] = attributes[j+3][k];
27334 k++;
27335 }
27336 }
27337 value[l] = '\0';
27338 /*
27339 * TODO: Set the node line.
27340 */
27341 ret = xmlSchemaValidatorPushAttribute(vctxt,
27342 NULL((void*)0), ielem->nodeLine, attributes[j], attributes[j+2], 0,
27343 value, 1);
27344 if (ret == -1) {
27345 VERROR_INT("xmlSchemaSAXHandleStartElementNs",xmlSchemaInternalErr((xmlSchemaAbstractCtxtPtr) vctxt, "xmlSchemaSAXHandleStartElementNs"
, "calling xmlSchemaValidatorPushAttribute()");
27346 "calling xmlSchemaValidatorPushAttribute()")xmlSchemaInternalErr((xmlSchemaAbstractCtxtPtr) vctxt, "xmlSchemaSAXHandleStartElementNs"
, "calling xmlSchemaValidatorPushAttribute()");
;
27347 goto internal_error;
27348 }
27349 }
27350 }
27351 /*
27352 * Validate the element.
27353 */
27354 ret = xmlSchemaValidateElem(vctxt);
27355 if (ret != 0) {
27356 if (ret == -1) {
27357 VERROR_INT("xmlSchemaSAXHandleStartElementNs",xmlSchemaInternalErr((xmlSchemaAbstractCtxtPtr) vctxt, "xmlSchemaSAXHandleStartElementNs"
, "calling xmlSchemaValidateElem()");
27358 "calling xmlSchemaValidateElem()")xmlSchemaInternalErr((xmlSchemaAbstractCtxtPtr) vctxt, "xmlSchemaSAXHandleStartElementNs"
, "calling xmlSchemaValidateElem()");
;
27359 goto internal_error;
27360 }
27361 goto exit;
27362 }
27363
27364exit:
27365 return;
27366internal_error:
27367 vctxt->err = -1;
27368 xmlStopParser(vctxt->parserCtxt);
27369 return;
27370}
27371
27372static void
27373xmlSchemaSAXHandleEndElementNs(void *ctx,
27374 const xmlChar * localname ATTRIBUTE_UNUSED__attribute__((unused)),
27375 const xmlChar * prefix ATTRIBUTE_UNUSED__attribute__((unused)),
27376 const xmlChar * URI ATTRIBUTE_UNUSED__attribute__((unused)))
27377{
27378 xmlSchemaValidCtxtPtr vctxt = (xmlSchemaValidCtxtPtr) ctx;
27379 int res;
27380
27381 /*
27382 * Skip elements if inside a "skip" wildcard or if invalid.
27383 */
27384 if (vctxt->skipDepth != -1) {
27385 if (vctxt->depth > vctxt->skipDepth) {
27386 vctxt->depth--;
27387 return;
27388 } else
27389 vctxt->skipDepth = -1;
27390 }
27391 /*
27392 * SAX VAL TODO: Just a temporary check.
27393 */
27394 if ((!xmlStrEqual(vctxt->inode->localName, localname)) ||
27395 (!xmlStrEqual(vctxt->inode->nsName, URI))) {
27396 VERROR_INT("xmlSchemaSAXHandleEndElementNs",xmlSchemaInternalErr((xmlSchemaAbstractCtxtPtr) vctxt, "xmlSchemaSAXHandleEndElementNs"
, "elem pop mismatch");
27397 "elem pop mismatch")xmlSchemaInternalErr((xmlSchemaAbstractCtxtPtr) vctxt, "xmlSchemaSAXHandleEndElementNs"
, "elem pop mismatch");
;
27398 }
27399 res = xmlSchemaValidatorPopElem(vctxt);
27400 if (res != 0) {
27401 if (res < 0) {
27402 VERROR_INT("xmlSchemaSAXHandleEndElementNs",xmlSchemaInternalErr((xmlSchemaAbstractCtxtPtr) vctxt, "xmlSchemaSAXHandleEndElementNs"
, "calling xmlSchemaValidatorPopElem()");
27403 "calling xmlSchemaValidatorPopElem()")xmlSchemaInternalErr((xmlSchemaAbstractCtxtPtr) vctxt, "xmlSchemaSAXHandleEndElementNs"
, "calling xmlSchemaValidatorPopElem()");
;
27404 goto internal_error;
27405 }
27406 goto exit;
27407 }
27408exit:
27409 return;
27410internal_error:
27411 vctxt->err = -1;
27412 xmlStopParser(vctxt->parserCtxt);
27413 return;
27414}
27415
27416/************************************************************************
27417 * *
27418 * Validation interfaces *
27419 * *
27420 ************************************************************************/
27421
27422/**
27423 * xmlSchemaNewValidCtxt:
27424 * @schema: a precompiled XML Schemas
27425 *
27426 * Create an XML Schemas validation context based on the given schema.
27427 *
27428 * Returns the validation context or NULL in case of error
27429 */
27430xmlSchemaValidCtxtPtr
27431xmlSchemaNewValidCtxt(xmlSchemaPtr schema)
27432{
27433 xmlSchemaValidCtxtPtr ret;
27434
27435 ret = (xmlSchemaValidCtxtPtr) xmlMalloc(sizeof(xmlSchemaValidCtxt));
27436 if (ret == NULL((void*)0)) {
27437 xmlSchemaVErrMemory(NULL((void*)0), "allocating validation context", NULL((void*)0));
27438 return (NULL((void*)0));
27439 }
27440 memset(ret, 0, sizeof(xmlSchemaValidCtxt));
27441 ret->type = XML_SCHEMA_CTXT_VALIDATOR2;
27442 ret->dict = xmlDictCreate();
27443 ret->nodeQNames = xmlSchemaItemListCreate();
27444 ret->schema = schema;
27445 return (ret);
27446}
27447
27448/**
27449 * xmlSchemaValidateSetFilename:
27450 * @vctxt: the schema validation context
27451 * @filename: the file name
27452 *
27453 * Workaround to provide file error reporting information when this is
27454 * not provided by current APIs
27455 */
27456void
27457xmlSchemaValidateSetFilename(xmlSchemaValidCtxtPtr vctxt, const char *filename) {
27458 if (vctxt == NULL((void*)0))
27459 return;
27460 if (vctxt->filename != NULL((void*)0))
27461 xmlFree(vctxt->filename);
27462 if (filename != NULL((void*)0))
27463 vctxt->filename = (char *) xmlStrdup((const xmlChar *) filename);
27464 else
27465 vctxt->filename = NULL((void*)0);
27466}
27467
27468/**
27469 * xmlSchemaClearValidCtxt:
27470 * @vctxt: the schema validation context
27471 *
27472 * Free the resources associated to the schema validation context;
27473 * leaves some fields alive intended for reuse of the context.
27474 */
27475static void
27476xmlSchemaClearValidCtxt(xmlSchemaValidCtxtPtr vctxt)
27477{
27478 if (vctxt == NULL((void*)0))
27479 return;
27480
27481 /*
27482 * TODO: Should we clear the flags?
27483 * Might be problematic if one reuses the context
27484 * and assumes that the options remain the same.
27485 */
27486 vctxt->flags = 0;
27487 vctxt->validationRoot = NULL((void*)0);
27488 vctxt->doc = NULL((void*)0);
27489#ifdef LIBXML_READER_ENABLED
27490 vctxt->reader = NULL((void*)0);
27491#endif
27492 vctxt->hasKeyrefs = 0;
27493
27494 if (vctxt->value != NULL((void*)0)) {
27495 xmlSchemaFreeValue(vctxt->value);
27496 vctxt->value = NULL((void*)0);
27497 }
27498 /*
27499 * Augmented IDC information.
27500 */
27501 if (vctxt->aidcs != NULL((void*)0)) {
27502 xmlSchemaIDCAugPtr cur = vctxt->aidcs, next;
27503 do {
27504 next = cur->next;
27505 xmlFree(cur);
27506 cur = next;
27507 } while (cur != NULL((void*)0));
27508 vctxt->aidcs = NULL((void*)0);
27509 }
27510
27511 if (vctxt->idcNodes != NULL((void*)0)) {
27512 int i;
27513 xmlSchemaPSVIIDCNodePtr item;
27514
27515 for (i = 0; i < vctxt->nbIdcNodes; i++) {
27516 item = vctxt->idcNodes[i];
27517 xmlFree(item->keys);
27518 xmlFree(item);
27519 }
27520 xmlFree(vctxt->idcNodes);
27521 vctxt->idcNodes = NULL((void*)0);
27522 vctxt->nbIdcNodes = 0;
27523 vctxt->sizeIdcNodes = 0;
27524 }
27525
27526 if (vctxt->idcKeys != NULL((void*)0)) {
27527 int i;
27528 for (i = 0; i < vctxt->nbIdcKeys; i++)
27529 xmlSchemaIDCFreeKey(vctxt->idcKeys[i]);
27530 xmlFree(vctxt->idcKeys);
27531 vctxt->idcKeys = NULL((void*)0);
27532 vctxt->nbIdcKeys = 0;
27533 vctxt->sizeIdcKeys = 0;
27534 }
27535
27536 /*
27537 * Note that we won't delete the XPath state pool here.
27538 */
27539 if (vctxt->xpathStates != NULL((void*)0)) {
27540 xmlSchemaFreeIDCStateObjList(vctxt->xpathStates);
27541 vctxt->xpathStates = NULL((void*)0);
27542 }
27543 /*
27544 * Attribute info.
27545 */
27546 if (vctxt->nbAttrInfos != 0) {
27547 xmlSchemaClearAttrInfos(vctxt);
27548 }
27549 /*
27550 * Element info.
27551 */
27552 if (vctxt->elemInfos != NULL((void*)0)) {
27553 int i;
27554 xmlSchemaNodeInfoPtr ei;
27555
27556 for (i = 0; i < vctxt->sizeElemInfos; i++) {
27557 ei = vctxt->elemInfos[i];
27558 if (ei == NULL((void*)0))
27559 break;
27560 xmlSchemaClearElemInfo(vctxt, ei);
27561 }
27562 }
27563 xmlSchemaItemListClear(vctxt->nodeQNames);
27564 /* Recreate the dict. */
27565 xmlDictFree(vctxt->dict);
27566 /*
27567 * TODO: Is is save to recreate it? Do we have a scenario
27568 * where the user provides the dict?
27569 */
27570 vctxt->dict = xmlDictCreate();
27571
27572 if (vctxt->filename != NULL((void*)0)) {
27573 xmlFree(vctxt->filename);
27574 vctxt->filename = NULL((void*)0);
27575 }
27576
27577 /*
27578 * Note that some cleanup functions can move items to the cache,
27579 * so the cache shouldn't be freed too early.
27580 */
27581 if (vctxt->idcMatcherCache != NULL((void*)0)) {
27582 xmlSchemaIDCMatcherPtr matcher = vctxt->idcMatcherCache, tmp;
27583
27584 while (matcher) {
27585 tmp = matcher;
27586 matcher = matcher->nextCached;
27587 xmlSchemaIDCFreeMatcherList(tmp);
27588 }
27589 vctxt->idcMatcherCache = NULL((void*)0);
27590 }
27591}
27592
27593/**
27594 * xmlSchemaFreeValidCtxt:
27595 * @ctxt: the schema validation context
27596 *
27597 * Free the resources associated to the schema validation context
27598 */
27599void
27600xmlSchemaFreeValidCtxt(xmlSchemaValidCtxtPtr ctxt)
27601{
27602 if (ctxt == NULL((void*)0))
27603 return;
27604 if (ctxt->value != NULL((void*)0))
27605 xmlSchemaFreeValue(ctxt->value);
27606 if (ctxt->pctxt != NULL((void*)0))
27607 xmlSchemaFreeParserCtxt(ctxt->pctxt);
27608 if (ctxt->idcNodes != NULL((void*)0)) {
27609 int i;
27610 xmlSchemaPSVIIDCNodePtr item;
27611
27612 for (i = 0; i < ctxt->nbIdcNodes; i++) {
27613 item = ctxt->idcNodes[i];
27614 xmlFree(item->keys);
27615 xmlFree(item);
27616 }
27617 xmlFree(ctxt->idcNodes);
27618 }
27619 if (ctxt->idcKeys != NULL((void*)0)) {
27620 int i;
27621 for (i = 0; i < ctxt->nbIdcKeys; i++)
27622 xmlSchemaIDCFreeKey(ctxt->idcKeys[i]);
27623 xmlFree(ctxt->idcKeys);
27624 }
27625
27626 if (ctxt->xpathStates != NULL((void*)0)) {
27627 xmlSchemaFreeIDCStateObjList(ctxt->xpathStates);
27628 ctxt->xpathStates = NULL((void*)0);
27629 }
27630 if (ctxt->xpathStatePool != NULL((void*)0)) {
27631 xmlSchemaFreeIDCStateObjList(ctxt->xpathStatePool);
27632 ctxt->xpathStatePool = NULL((void*)0);
27633 }
27634
27635 /*
27636 * Augmented IDC information.
27637 */
27638 if (ctxt->aidcs != NULL((void*)0)) {
27639 xmlSchemaIDCAugPtr cur = ctxt->aidcs, next;
27640 do {
27641 next = cur->next;
27642 xmlFree(cur);
27643 cur = next;
27644 } while (cur != NULL((void*)0));
27645 }
27646 if (ctxt->attrInfos != NULL((void*)0)) {
27647 int i;
27648 xmlSchemaAttrInfoPtr attr;
27649
27650 /* Just a paranoid call to the cleanup. */
27651 if (ctxt->nbAttrInfos != 0)
27652 xmlSchemaClearAttrInfos(ctxt);
27653 for (i = 0; i < ctxt->sizeAttrInfos; i++) {
27654 attr = ctxt->attrInfos[i];
27655 xmlFree(attr);
27656 }
27657 xmlFree(ctxt->attrInfos);
27658 }
27659 if (ctxt->elemInfos != NULL((void*)0)) {
27660 int i;
27661 xmlSchemaNodeInfoPtr ei;
27662
27663 for (i = 0; i < ctxt->sizeElemInfos; i++) {
27664 ei = ctxt->elemInfos[i];
27665 if (ei == NULL((void*)0))
27666 break;
27667 xmlSchemaClearElemInfo(ctxt, ei);
27668 xmlFree(ei);
27669 }
27670 xmlFree(ctxt->elemInfos);
27671 }
27672 if (ctxt->nodeQNames != NULL((void*)0))
27673 xmlSchemaItemListFree(ctxt->nodeQNames);
27674 if (ctxt->dict != NULL((void*)0))
27675 xmlDictFree(ctxt->dict);
27676 if (ctxt->filename != NULL((void*)0))
27677 xmlFree(ctxt->filename);
27678 xmlFree(ctxt);
27679}
27680
27681/**
27682 * xmlSchemaIsValid:
27683 * @ctxt: the schema validation context
27684 *
27685 * Check if any error was detected during validation.
27686 *
27687 * Returns 1 if valid so far, 0 if errors were detected, and -1 in case
27688 * of internal error.
27689 */
27690int
27691xmlSchemaIsValid(xmlSchemaValidCtxtPtr ctxt)
27692{
27693 if (ctxt == NULL((void*)0))
27694 return(-1);
27695 return(ctxt->err == 0);
27696}
27697
27698/**
27699 * xmlSchemaSetValidErrors:
27700 * @ctxt: a schema validation context
27701 * @err: the error function
27702 * @warn: the warning function
27703 * @ctx: the functions context
27704 *
27705 * Set the error and warning callback information
27706 */
27707void
27708xmlSchemaSetValidErrors(xmlSchemaValidCtxtPtr ctxt,
27709 xmlSchemaValidityErrorFunc err,
27710 xmlSchemaValidityWarningFunc warn, void *ctx)
27711{
27712 if (ctxt == NULL((void*)0))
27713 return;
27714 ctxt->error = err;
27715 ctxt->warning = warn;
27716 ctxt->errCtxt = ctx;
27717 if (ctxt->pctxt != NULL((void*)0))
27718 xmlSchemaSetParserErrors(ctxt->pctxt, err, warn, ctx);
27719}
27720
27721/**
27722 * xmlSchemaSetValidStructuredErrors:
27723 * @ctxt: a schema validation context
27724 * @serror: the structured error function
27725 * @ctx: the functions context
27726 *
27727 * Set the structured error callback
27728 */
27729void
27730xmlSchemaSetValidStructuredErrors(xmlSchemaValidCtxtPtr ctxt,
27731 xmlStructuredErrorFunc serror, void *ctx)
27732{
27733 if (ctxt == NULL((void*)0))
27734 return;
27735 ctxt->serror = serror;
27736 ctxt->error = NULL((void*)0);
27737 ctxt->warning = NULL((void*)0);
27738 ctxt->errCtxt = ctx;
27739 if (ctxt->pctxt != NULL((void*)0))
27740 xmlSchemaSetParserStructuredErrors(ctxt->pctxt, serror, ctx);
27741}
27742
27743/**
27744 * xmlSchemaGetValidErrors:
27745 * @ctxt: a XML-Schema validation context
27746 * @err: the error function result
27747 * @warn: the warning function result
27748 * @ctx: the functions context result
27749 *
27750 * Get the error and warning callback information
27751 *
27752 * Returns -1 in case of error and 0 otherwise
27753 */
27754int
27755xmlSchemaGetValidErrors(xmlSchemaValidCtxtPtr ctxt,
27756 xmlSchemaValidityErrorFunc * err,
27757 xmlSchemaValidityWarningFunc * warn, void **ctx)
27758{
27759 if (ctxt == NULL((void*)0))
27760 return (-1);
27761 if (err != NULL((void*)0))
27762 *err = ctxt->error;
27763 if (warn != NULL((void*)0))
27764 *warn = ctxt->warning;
27765 if (ctx != NULL((void*)0))
27766 *ctx = ctxt->errCtxt;
27767 return (0);
27768}
27769
27770
27771/**
27772 * xmlSchemaSetValidOptions:
27773 * @ctxt: a schema validation context
27774 * @options: a combination of xmlSchemaValidOption
27775 *
27776 * Sets the options to be used during the validation.
27777 *
27778 * Returns 0 in case of success, -1 in case of an
27779 * API error.
27780 */
27781int
27782xmlSchemaSetValidOptions(xmlSchemaValidCtxtPtr ctxt,
27783 int options)
27784
27785{
27786 int i;
27787
27788 if (ctxt == NULL((void*)0))
27789 return (-1);
27790 /*
27791 * WARNING: Change the start value if adding to the
27792 * xmlSchemaValidOption.
27793 * TODO: Is there an other, more easy to maintain,
27794 * way?
27795 */
27796 for (i = 1; i < (int) sizeof(int) * 8; i++) {
27797 if (options & 1<<i)
27798 return (-1);
27799 }
27800 ctxt->options = options;
27801 return (0);
27802}
27803
27804/**
27805 * xmlSchemaValidCtxtGetOptions:
27806 * @ctxt: a schema validation context
27807 *
27808 * Get the validation context options.
27809 *
27810 * Returns the option combination or -1 on error.
27811 */
27812int
27813xmlSchemaValidCtxtGetOptions(xmlSchemaValidCtxtPtr ctxt)
27814
27815{
27816 if (ctxt == NULL((void*)0))
27817 return (-1);
27818 else
27819 return (ctxt->options);
27820}
27821
27822static int
27823xmlSchemaVDocWalk(xmlSchemaValidCtxtPtr vctxt)
27824{
27825 xmlAttrPtr attr;
27826 int ret = 0;
27827 xmlSchemaNodeInfoPtr ielem = NULL((void*)0);
27828 xmlNodePtr node, valRoot;
27829 const xmlChar *nsName;
27830
27831 /* DOC VAL TODO: Move this to the start function. */
27832 if (vctxt->validationRoot != NULL((void*)0))
27833 valRoot = vctxt->validationRoot;
27834 else
27835 valRoot = xmlDocGetRootElement(vctxt->doc);
27836 if (valRoot == NULL((void*)0)) {
27837 /* VAL TODO: Error code? */
27838 VERROR(1, NULL, "The document has no document element")xmlSchemaCustomErr((xmlSchemaAbstractCtxtPtr) vctxt, 1, ((void
*)0), ((void*)0), "The document has no document element", ((void
*)0), ((void*)0));
;
27839 return (1);
27840 }
27841 vctxt->depth = -1;
27842 vctxt->validationRoot = valRoot;
27843 node = valRoot;
27844 while (node != NULL((void*)0)) {
27845 if ((vctxt->skipDepth != -1) && (vctxt->depth >= vctxt->skipDepth))
27846 goto next_sibling;
27847 if (node->type == XML_ELEMENT_NODE) {
27848
27849 /*
27850 * Init the node-info.
27851 */
27852 vctxt->depth++;
27853 if (xmlSchemaValidatorPushElem(vctxt) == -1)
27854 goto internal_error;
27855 ielem = vctxt->inode;
27856 ielem->node = node;
27857 ielem->nodeLine = node->line;
27858 ielem->localName = node->name;
27859 if (node->ns != NULL((void*)0))
27860 ielem->nsName = node->ns->href;
27861 ielem->flags |= XML_SCHEMA_ELEM_INFO_EMPTY1<<5;
27862 /*
27863 * Register attributes.
27864 * DOC VAL TODO: We do not register namespace declaration
27865 * attributes yet.
27866 */
27867 vctxt->nbAttrInfos = 0;
27868 if (node->properties != NULL((void*)0)) {
27869 attr = node->properties;
27870 do {
27871 if (attr->ns != NULL((void*)0))
27872 nsName = attr->ns->href;
27873 else
27874 nsName = NULL((void*)0);
27875 ret = xmlSchemaValidatorPushAttribute(vctxt,
27876 (xmlNodePtr) attr,
27877 /*
27878 * Note that we give it the line number of the
27879 * parent element.
27880 */
27881 ielem->nodeLine,
27882 attr->name, nsName, 0,
27883 xmlNodeListGetString(attr->doc, attr->children, 1), 1);
27884 if (ret == -1) {
27885 VERROR_INT("xmlSchemaDocWalk",xmlSchemaInternalErr((xmlSchemaAbstractCtxtPtr) vctxt, "xmlSchemaDocWalk"
, "calling xmlSchemaValidatorPushAttribute()");
27886 "calling xmlSchemaValidatorPushAttribute()")xmlSchemaInternalErr((xmlSchemaAbstractCtxtPtr) vctxt, "xmlSchemaDocWalk"
, "calling xmlSchemaValidatorPushAttribute()");
;
27887 goto internal_error;
27888 }
27889 attr = attr->next;
27890 } while (attr);
27891 }
27892 /*
27893 * Validate the element.
27894 */
27895 ret = xmlSchemaValidateElem(vctxt);
27896 if (ret != 0) {
27897 if (ret == -1) {
27898 VERROR_INT("xmlSchemaDocWalk",xmlSchemaInternalErr((xmlSchemaAbstractCtxtPtr) vctxt, "xmlSchemaDocWalk"
, "calling xmlSchemaValidateElem()");
27899 "calling xmlSchemaValidateElem()")xmlSchemaInternalErr((xmlSchemaAbstractCtxtPtr) vctxt, "xmlSchemaDocWalk"
, "calling xmlSchemaValidateElem()");
;
27900 goto internal_error;
27901 }
27902 /*
27903 * Don't stop validation; just skip the content
27904 * of this element.
27905 */
27906 goto leave_node;
27907 }
27908 if ((vctxt->skipDepth != -1) &&
27909 (vctxt->depth >= vctxt->skipDepth))
27910 goto leave_node;
27911 } else if ((node->type == XML_TEXT_NODE) ||
27912 (node->type == XML_CDATA_SECTION_NODE)) {
27913 /*
27914 * Process character content.
27915 */
27916 if ((ielem != NULL((void*)0)) && (ielem->flags & XML_SCHEMA_ELEM_INFO_EMPTY1<<5))
27917 ielem->flags ^= XML_SCHEMA_ELEM_INFO_EMPTY1<<5;
27918 ret = xmlSchemaVPushText(vctxt, node->type, node->content,
27919 -1, XML_SCHEMA_PUSH_TEXT_PERSIST1, NULL((void*)0));
27920 if (ret < 0) {
27921 VERROR_INT("xmlSchemaVDocWalk",xmlSchemaInternalErr((xmlSchemaAbstractCtxtPtr) vctxt, "xmlSchemaVDocWalk"
, "calling xmlSchemaVPushText()");
27922 "calling xmlSchemaVPushText()")xmlSchemaInternalErr((xmlSchemaAbstractCtxtPtr) vctxt, "xmlSchemaVDocWalk"
, "calling xmlSchemaVPushText()");
;
27923 goto internal_error;
27924 }
27925 /*
27926 * DOC VAL TODO: Should we skip further validation of the
27927 * element content here?
27928 */
27929 } else if ((node->type == XML_ENTITY_NODE) ||
27930 (node->type == XML_ENTITY_REF_NODE)) {
27931 /*
27932 * DOC VAL TODO: What to do with entities?
27933 */
27934 VERROR_INT("xmlSchemaVDocWalk",xmlSchemaInternalErr((xmlSchemaAbstractCtxtPtr) vctxt, "xmlSchemaVDocWalk"
, "there is at least one entity reference in the node-tree " "currently being validated. Processing of entities with "
"this XML Schema processor is not supported (yet). Please " "substitute entities before validation."
);
27935 "there is at least one entity reference in the node-tree "xmlSchemaInternalErr((xmlSchemaAbstractCtxtPtr) vctxt, "xmlSchemaVDocWalk"
, "there is at least one entity reference in the node-tree " "currently being validated. Processing of entities with "
"this XML Schema processor is not supported (yet). Please " "substitute entities before validation."
);
27936 "currently being validated. Processing of entities with "xmlSchemaInternalErr((xmlSchemaAbstractCtxtPtr) vctxt, "xmlSchemaVDocWalk"
, "there is at least one entity reference in the node-tree " "currently being validated. Processing of entities with "
"this XML Schema processor is not supported (yet). Please " "substitute entities before validation."
);
27937 "this XML Schema processor is not supported (yet). Please "xmlSchemaInternalErr((xmlSchemaAbstractCtxtPtr) vctxt, "xmlSchemaVDocWalk"
, "there is at least one entity reference in the node-tree " "currently being validated. Processing of entities with "
"this XML Schema processor is not supported (yet). Please " "substitute entities before validation."
);
27938 "substitute entities before validation.")xmlSchemaInternalErr((xmlSchemaAbstractCtxtPtr) vctxt, "xmlSchemaVDocWalk"
, "there is at least one entity reference in the node-tree " "currently being validated. Processing of entities with "
"this XML Schema processor is not supported (yet). Please " "substitute entities before validation."
);
;
27939 goto internal_error;
27940 } else {
27941 goto leave_node;
27942 /*
27943 * DOC VAL TODO: XInclude nodes, etc.
27944 */
27945 }
27946 /*
27947 * Walk the doc.
27948 */
27949 if (node->children != NULL((void*)0)) {
27950 node = node->children;
27951 continue;
27952 }
27953leave_node:
27954 if (node->type == XML_ELEMENT_NODE) {
27955 /*
27956 * Leaving the scope of an element.
27957 */
27958 if (node != vctxt->inode->node) {
27959 VERROR_INT("xmlSchemaVDocWalk",xmlSchemaInternalErr((xmlSchemaAbstractCtxtPtr) vctxt, "xmlSchemaVDocWalk"
, "element position mismatch");
27960 "element position mismatch")xmlSchemaInternalErr((xmlSchemaAbstractCtxtPtr) vctxt, "xmlSchemaVDocWalk"
, "element position mismatch");
;
27961 goto internal_error;
27962 }
27963 ret = xmlSchemaValidatorPopElem(vctxt);
27964 if (ret != 0) {
27965 if (ret < 0) {
27966 VERROR_INT("xmlSchemaVDocWalk",xmlSchemaInternalErr((xmlSchemaAbstractCtxtPtr) vctxt, "xmlSchemaVDocWalk"
, "calling xmlSchemaValidatorPopElem()");
27967 "calling xmlSchemaValidatorPopElem()")xmlSchemaInternalErr((xmlSchemaAbstractCtxtPtr) vctxt, "xmlSchemaVDocWalk"
, "calling xmlSchemaValidatorPopElem()");
;
27968 goto internal_error;
27969 }
27970 }
27971 if (node == valRoot)
27972 goto exit;
27973 }
27974next_sibling:
27975 if (node->next != NULL((void*)0))
27976 node = node->next;
27977 else {
27978 node = node->parent;
27979 goto leave_node;
27980 }
27981 }
27982
27983exit:
27984 return (ret);
27985internal_error:
27986 return (-1);
27987}
27988
27989static int
27990xmlSchemaPreRun(xmlSchemaValidCtxtPtr vctxt) {
27991 /*
27992 * Some initialization.
27993 */
27994 vctxt->err = 0;
27995 vctxt->nberrors = 0;
27996 vctxt->depth = -1;
27997 vctxt->skipDepth = -1;
27998 vctxt->hasKeyrefs = 0;
27999#ifdef ENABLE_IDC_NODE_TABLES_TEST
28000 vctxt->createIDCNodeTables = 1;
28001#else
28002 vctxt->createIDCNodeTables = 0;
28003#endif
28004 /*
28005 * Create a schema + parser if necessary.
28006 */
28007 if (vctxt->schema == NULL((void*)0)) {
28008 xmlSchemaParserCtxtPtr pctxt;
28009
28010 vctxt->xsiAssemble = 1;
28011 /*
28012 * If not schema was given then we will create a schema
28013 * dynamically using XSI schema locations.
28014 *
28015 * Create the schema parser context.
28016 */
28017 if ((vctxt->pctxt == NULL((void*)0)) &&
28018 (xmlSchemaCreatePCtxtOnVCtxt(vctxt) == -1))
28019 return (-1);
28020 pctxt = vctxt->pctxt;
28021 pctxt->xsiAssemble = 1;
28022 /*
28023 * Create the schema.
28024 */
28025 vctxt->schema = xmlSchemaNewSchema(pctxt);
28026 if (vctxt->schema == NULL((void*)0))
28027 return (-1);
28028 /*
28029 * Create the schema construction context.
28030 */
28031 pctxt->constructor = xmlSchemaConstructionCtxtCreate(pctxt->dict);
28032 if (pctxt->constructor == NULL((void*)0))
28033 return(-1);
28034 pctxt->constructor->mainSchema = vctxt->schema;
28035 /*
28036 * Take ownership of the constructor to be able to free it.
28037 */
28038 pctxt->ownsConstructor = 1;
28039 }
28040 /*
28041 * Augment the IDC definitions for the main schema and all imported ones
28042 * NOTE: main schema if the first in the imported list
28043 */
28044 xmlHashScan(vctxt->schema->schemasImports, xmlSchemaAugmentImportedIDC,
28045 vctxt);
28046
28047 return(0);
28048}
28049
28050static void
28051xmlSchemaPostRun(xmlSchemaValidCtxtPtr vctxt) {
28052 if (vctxt->xsiAssemble) {
28053 if (vctxt->schema != NULL((void*)0)) {
28054 xmlSchemaFree(vctxt->schema);
28055 vctxt->schema = NULL((void*)0);
28056 }
28057 }
28058 xmlSchemaClearValidCtxt(vctxt);
28059}
28060
28061static int
28062xmlSchemaVStart(xmlSchemaValidCtxtPtr vctxt)
28063{
28064 int ret = 0;
28065
28066 if (xmlSchemaPreRun(vctxt) < 0)
28067 return(-1);
28068
28069 if (vctxt->doc != NULL((void*)0)) {
28070 /*
28071 * Tree validation.
28072 */
28073 ret = xmlSchemaVDocWalk(vctxt);
28074#ifdef LIBXML_READER_ENABLED
28075 } else if (vctxt->reader != NULL((void*)0)) {
28076 /*
28077 * XML Reader validation.
28078 */
28079#ifdef XML_SCHEMA_READER_ENABLED
28080 ret = xmlSchemaVReaderWalk(vctxt);
28081#endif
28082#endif
28083 } else if ((vctxt->sax != NULL((void*)0)) && (vctxt->parserCtxt != NULL((void*)0))) {
28084 /*
28085 * SAX validation.
28086 */
28087 ret = xmlParseDocument(vctxt->parserCtxt);
28088 } else {
28089 VERROR_INT("xmlSchemaVStart",xmlSchemaInternalErr((xmlSchemaAbstractCtxtPtr) vctxt, "xmlSchemaVStart"
, "no instance to validate");
28090 "no instance to validate")xmlSchemaInternalErr((xmlSchemaAbstractCtxtPtr) vctxt, "xmlSchemaVStart"
, "no instance to validate");
;
28091 ret = -1;
28092 }
28093
28094 xmlSchemaPostRun(vctxt);
28095 if (ret == 0)
28096 ret = vctxt->err;
28097 return (ret);
28098}
28099
28100/**
28101 * xmlSchemaValidateOneElement:
28102 * @ctxt: a schema validation context
28103 * @elem: an element node
28104 *
28105 * Validate a branch of a tree, starting with the given @elem.
28106 *
28107 * Returns 0 if the element and its subtree is valid, a positive error
28108 * code number otherwise and -1 in case of an internal or API error.
28109 */
28110int
28111xmlSchemaValidateOneElement(xmlSchemaValidCtxtPtr ctxt, xmlNodePtr elem)
28112{
28113 if ((ctxt == NULL((void*)0)) || (elem == NULL((void*)0)) || (elem->type != XML_ELEMENT_NODE))
28114 return (-1);
28115
28116 if (ctxt->schema == NULL((void*)0))
28117 return (-1);
28118
28119 ctxt->doc = elem->doc;
28120 ctxt->node = elem;
28121 ctxt->validationRoot = elem;
28122 return(xmlSchemaVStart(ctxt));
28123}
28124
28125/**
28126 * xmlSchemaValidateDoc:
28127 * @ctxt: a schema validation context
28128 * @doc: a parsed document tree
28129 *
28130 * Validate a document tree in memory.
28131 *
28132 * Returns 0 if the document is schemas valid, a positive error code
28133 * number otherwise and -1 in case of internal or API error.
28134 */
28135int
28136xmlSchemaValidateDoc(xmlSchemaValidCtxtPtr ctxt, xmlDocPtr doc)
28137{
28138 if ((ctxt == NULL((void*)0)) || (doc == NULL((void*)0)))
28139 return (-1);
28140
28141 ctxt->doc = doc;
28142 ctxt->node = xmlDocGetRootElement(doc);
28143 if (ctxt->node == NULL((void*)0)) {
28144 xmlSchemaCustomErr(ACTXT_CAST(xmlSchemaAbstractCtxtPtr) ctxt,
28145 XML_SCHEMAV_DOCUMENT_ELEMENT_MISSING,
28146 (xmlNodePtr) doc, NULL((void*)0),
28147 "The document has no document element", NULL((void*)0), NULL((void*)0));
28148 return (ctxt->err);
28149 }
28150 ctxt->validationRoot = ctxt->node;
28151 return (xmlSchemaVStart(ctxt));
28152}
28153
28154
28155/************************************************************************
28156 * *
28157 * Function and data for SAX streaming API *
28158 * *
28159 ************************************************************************/
28160typedef struct _xmlSchemaSplitSAXData xmlSchemaSplitSAXData;
28161typedef xmlSchemaSplitSAXData *xmlSchemaSplitSAXDataPtr;
28162
28163struct _xmlSchemaSplitSAXData {
28164 xmlSAXHandlerPtr user_sax;
28165 void *user_data;
28166 xmlSchemaValidCtxtPtr ctxt;
28167 xmlSAXHandlerPtr schemas_sax;
28168};
28169
28170#define XML_SAX_PLUG_MAGIC0xdc43ba21 0xdc43ba21
28171
28172struct _xmlSchemaSAXPlug {
28173 unsigned int magic;
28174
28175 /* the original callbacks information */
28176 xmlSAXHandlerPtr *user_sax_ptr;
28177 xmlSAXHandlerPtr user_sax;
28178 void **user_data_ptr;
28179 void *user_data;
28180
28181 /* the block plugged back and validation information */
28182 xmlSAXHandler schemas_sax;
28183 xmlSchemaValidCtxtPtr ctxt;
28184};
28185
28186/* All those functions just bounces to the user provided SAX handlers */
28187static void
28188internalSubsetSplit(void *ctx, const xmlChar *name,
28189 const xmlChar *ExternalID, const xmlChar *SystemID)
28190{
28191 xmlSchemaSAXPlugPtr ctxt = (xmlSchemaSAXPlugPtr) ctx;
28192 if ((ctxt != NULL((void*)0)) && (ctxt->user_sax != NULL((void*)0)) &&
28193 (ctxt->user_sax->internalSubset != NULL((void*)0)))
28194 ctxt->user_sax->internalSubset(ctxt->user_data, name, ExternalID,
28195 SystemID);
28196}
28197
28198static int
28199isStandaloneSplit(void *ctx)
28200{
28201 xmlSchemaSAXPlugPtr ctxt = (xmlSchemaSAXPlugPtr) ctx;
28202 if ((ctxt != NULL((void*)0)) && (ctxt->user_sax != NULL((void*)0)) &&
28203 (ctxt->user_sax->isStandalone != NULL((void*)0)))
28204 return(ctxt->user_sax->isStandalone(ctxt->user_data));
28205 return(0);
28206}
28207
28208static int
28209hasInternalSubsetSplit(void *ctx)
28210{
28211 xmlSchemaSAXPlugPtr ctxt = (xmlSchemaSAXPlugPtr) ctx;
28212 if ((ctxt != NULL((void*)0)) && (ctxt->user_sax != NULL((void*)0)) &&
28213 (ctxt->user_sax->hasInternalSubset != NULL((void*)0)))
28214 return(ctxt->user_sax->hasInternalSubset(ctxt->user_data));
28215 return(0);
28216}
28217
28218static int
28219hasExternalSubsetSplit(void *ctx)
28220{
28221 xmlSchemaSAXPlugPtr ctxt = (xmlSchemaSAXPlugPtr) ctx;
28222 if ((ctxt != NULL((void*)0)) && (ctxt->user_sax != NULL((void*)0)) &&
28223 (ctxt->user_sax->hasExternalSubset != NULL((void*)0)))
28224 return(ctxt->user_sax->hasExternalSubset(ctxt->user_data));
28225 return(0);
28226}
28227
28228static void
28229externalSubsetSplit(void *ctx, const xmlChar *name,
28230 const xmlChar *ExternalID, const xmlChar *SystemID)
28231{
28232 xmlSchemaSAXPlugPtr ctxt = (xmlSchemaSAXPlugPtr) ctx;
28233 if ((ctxt != NULL((void*)0)) && (ctxt->user_sax != NULL((void*)0)) &&
28234 (ctxt->user_sax->externalSubset != NULL((void*)0)))
28235 ctxt->user_sax->externalSubset(ctxt->user_data, name, ExternalID,
28236 SystemID);
28237}
28238
28239static xmlParserInputPtr
28240resolveEntitySplit(void *ctx, const xmlChar *publicId, const xmlChar *systemId)
28241{
28242 xmlSchemaSAXPlugPtr ctxt = (xmlSchemaSAXPlugPtr) ctx;
28243 if ((ctxt != NULL((void*)0)) && (ctxt->user_sax != NULL((void*)0)) &&
28244 (ctxt->user_sax->resolveEntity != NULL((void*)0)))
28245 return(ctxt->user_sax->resolveEntity(ctxt->user_data, publicId,
28246 systemId));
28247 return(NULL((void*)0));
28248}
28249
28250static xmlEntityPtr
28251getEntitySplit(void *ctx, const xmlChar *name)
28252{
28253 xmlSchemaSAXPlugPtr ctxt = (xmlSchemaSAXPlugPtr) ctx;
28254 if ((ctxt != NULL((void*)0)) && (ctxt->user_sax != NULL((void*)0)) &&
28255 (ctxt->user_sax->getEntity != NULL((void*)0)))
28256 return(ctxt->user_sax->getEntity(ctxt->user_data, name));
28257 return(NULL((void*)0));
28258}
28259
28260static xmlEntityPtr
28261getParameterEntitySplit(void *ctx, const xmlChar *name)
28262{
28263 xmlSchemaSAXPlugPtr ctxt = (xmlSchemaSAXPlugPtr) ctx;
28264 if ((ctxt != NULL((void*)0)) && (ctxt->user_sax != NULL((void*)0)) &&
28265 (ctxt->user_sax->getParameterEntity != NULL((void*)0)))
28266 return(ctxt->user_sax->getParameterEntity(ctxt->user_data, name));
28267 return(NULL((void*)0));
28268}
28269
28270
28271static void
28272entityDeclSplit(void *ctx, const xmlChar *name, int type,
28273 const xmlChar *publicId, const xmlChar *systemId, xmlChar *content)
28274{
28275 xmlSchemaSAXPlugPtr ctxt = (xmlSchemaSAXPlugPtr) ctx;
28276 if ((ctxt != NULL((void*)0)) && (ctxt->user_sax != NULL((void*)0)) &&
28277 (ctxt->user_sax->entityDecl != NULL((void*)0)))
28278 ctxt->user_sax->entityDecl(ctxt->user_data, name, type, publicId,
28279 systemId, content);
28280}
28281
28282static void
28283attributeDeclSplit(void *ctx, const xmlChar * elem,
28284 const xmlChar * name, int type, int def,
28285 const xmlChar * defaultValue, xmlEnumerationPtr tree)
28286{
28287 xmlSchemaSAXPlugPtr ctxt = (xmlSchemaSAXPlugPtr) ctx;
28288 if ((ctxt != NULL((void*)0)) && (ctxt->user_sax != NULL((void*)0)) &&
28289 (ctxt->user_sax->attributeDecl != NULL((void*)0))) {
28290 ctxt->user_sax->attributeDecl(ctxt->user_data, elem, name, type,
28291 def, defaultValue, tree);
28292 } else {
28293 xmlFreeEnumeration(tree);
28294 }
28295}
28296
28297static void
28298elementDeclSplit(void *ctx, const xmlChar *name, int type,
28299 xmlElementContentPtr content)
28300{
28301 xmlSchemaSAXPlugPtr ctxt = (xmlSchemaSAXPlugPtr) ctx;
28302 if ((ctxt != NULL((void*)0)) && (ctxt->user_sax != NULL((void*)0)) &&
28303 (ctxt->user_sax->elementDecl != NULL((void*)0)))
28304 ctxt->user_sax->elementDecl(ctxt->user_data, name, type, content);
28305}
28306
28307static void
28308notationDeclSplit(void *ctx, const xmlChar *name,
28309 const xmlChar *publicId, const xmlChar *systemId)
28310{
28311 xmlSchemaSAXPlugPtr ctxt = (xmlSchemaSAXPlugPtr) ctx;
28312 if ((ctxt != NULL((void*)0)) && (ctxt->user_sax != NULL((void*)0)) &&
28313 (ctxt->user_sax->notationDecl != NULL((void*)0)))
28314 ctxt->user_sax->notationDecl(ctxt->user_data, name, publicId,
28315 systemId);
28316}
28317
28318static void
28319unparsedEntityDeclSplit(void *ctx, const xmlChar *name,
28320 const xmlChar *publicId, const xmlChar *systemId,
28321 const xmlChar *notationName)
28322{
28323 xmlSchemaSAXPlugPtr ctxt = (xmlSchemaSAXPlugPtr) ctx;
28324 if ((ctxt != NULL((void*)0)) && (ctxt->user_sax != NULL((void*)0)) &&
28325 (ctxt->user_sax->unparsedEntityDecl != NULL((void*)0)))
28326 ctxt->user_sax->unparsedEntityDecl(ctxt->user_data, name, publicId,
28327 systemId, notationName);
28328}
28329
28330static void
28331setDocumentLocatorSplit(void *ctx, xmlSAXLocatorPtr loc)
28332{
28333 xmlSchemaSAXPlugPtr ctxt = (xmlSchemaSAXPlugPtr) ctx;
28334 if ((ctxt != NULL((void*)0)) && (ctxt->user_sax != NULL((void*)0)) &&
28335 (ctxt->user_sax->setDocumentLocator != NULL((void*)0)))
28336 ctxt->user_sax->setDocumentLocator(ctxt->user_data, loc);
28337}
28338
28339static void
28340startDocumentSplit(void *ctx)
28341{
28342 xmlSchemaSAXPlugPtr ctxt = (xmlSchemaSAXPlugPtr) ctx;
28343 if ((ctxt != NULL((void*)0)) && (ctxt->user_sax != NULL((void*)0)) &&
28344 (ctxt->user_sax->startDocument != NULL((void*)0)))
28345 ctxt->user_sax->startDocument(ctxt->user_data);
28346}
28347
28348static void
28349endDocumentSplit(void *ctx)
28350{
28351 xmlSchemaSAXPlugPtr ctxt = (xmlSchemaSAXPlugPtr) ctx;
28352 if ((ctxt != NULL((void*)0)) && (ctxt->user_sax != NULL((void*)0)) &&
28353 (ctxt->user_sax->endDocument != NULL((void*)0)))
28354 ctxt->user_sax->endDocument(ctxt->user_data);
28355}
28356
28357static void
28358processingInstructionSplit(void *ctx, const xmlChar *target,
28359 const xmlChar *data)
28360{
28361 xmlSchemaSAXPlugPtr ctxt = (xmlSchemaSAXPlugPtr) ctx;
28362 if ((ctxt != NULL((void*)0)) && (ctxt->user_sax != NULL((void*)0)) &&
28363 (ctxt->user_sax->processingInstruction != NULL((void*)0)))
28364 ctxt->user_sax->processingInstruction(ctxt->user_data, target, data);
28365}
28366
28367static void
28368commentSplit(void *ctx, const xmlChar *value)
28369{
28370 xmlSchemaSAXPlugPtr ctxt = (xmlSchemaSAXPlugPtr) ctx;
28371 if ((ctxt != NULL((void*)0)) && (ctxt->user_sax != NULL((void*)0)) &&
28372 (ctxt->user_sax->comment != NULL((void*)0)))
28373 ctxt->user_sax->comment(ctxt->user_data, value);
28374}
28375
28376/*
28377 * Varargs error callbacks to the user application, harder ...
28378 */
28379
28380static void
28381warningSplit(void *ctx, const char *msg ATTRIBUTE_UNUSED__attribute__((unused)), ...) {
28382 xmlSchemaSAXPlugPtr ctxt = (xmlSchemaSAXPlugPtr) ctx;
28383 if ((ctxt != NULL((void*)0)) && (ctxt->user_sax != NULL((void*)0)) &&
28384 (ctxt->user_sax->warning != NULL((void*)0))) {
28385 TODO(*__xmlGenericError())((*__xmlGenericErrorContext()), "Unimplemented block at %s:%d\n"
, "xmlschemas.c", 28385);
28386 }
28387}
28388static void
28389errorSplit(void *ctx, const char *msg ATTRIBUTE_UNUSED__attribute__((unused)), ...) {
28390 xmlSchemaSAXPlugPtr ctxt = (xmlSchemaSAXPlugPtr) ctx;
28391 if ((ctxt != NULL((void*)0)) && (ctxt->user_sax != NULL((void*)0)) &&
28392 (ctxt->user_sax->error != NULL((void*)0))) {
28393 TODO(*__xmlGenericError())((*__xmlGenericErrorContext()), "Unimplemented block at %s:%d\n"
, "xmlschemas.c", 28393);
28394 }
28395}
28396static void
28397fatalErrorSplit(void *ctx, const char *msg ATTRIBUTE_UNUSED__attribute__((unused)), ...) {
28398 xmlSchemaSAXPlugPtr ctxt = (xmlSchemaSAXPlugPtr) ctx;
28399 if ((ctxt != NULL((void*)0)) && (ctxt->user_sax != NULL((void*)0)) &&
28400 (ctxt->user_sax->fatalError != NULL((void*)0))) {
28401 TODO(*__xmlGenericError())((*__xmlGenericErrorContext()), "Unimplemented block at %s:%d\n"
, "xmlschemas.c", 28401);
28402 }
28403}
28404
28405/*
28406 * Those are function where both the user handler and the schemas handler
28407 * need to be called.
28408 */
28409static void
28410charactersSplit(void *ctx, const xmlChar *ch, int len)
28411{
28412 xmlSchemaSAXPlugPtr ctxt = (xmlSchemaSAXPlugPtr) ctx;
28413 if (ctxt == NULL((void*)0))
28414 return;
28415 if ((ctxt->user_sax != NULL((void*)0)) && (ctxt->user_sax->characters != NULL((void*)0)))
28416 ctxt->user_sax->characters(ctxt->user_data, ch, len);
28417 if (ctxt->ctxt != NULL((void*)0))
28418 xmlSchemaSAXHandleText(ctxt->ctxt, ch, len);
28419}
28420
28421static void
28422ignorableWhitespaceSplit(void *ctx, const xmlChar *ch, int len)
28423{
28424 xmlSchemaSAXPlugPtr ctxt = (xmlSchemaSAXPlugPtr) ctx;
28425 if (ctxt == NULL((void*)0))
28426 return;
28427 if ((ctxt->user_sax != NULL((void*)0)) &&
28428 (ctxt->user_sax->ignorableWhitespace != NULL((void*)0)))
28429 ctxt->user_sax->ignorableWhitespace(ctxt->user_data, ch, len);
28430 if (ctxt->ctxt != NULL((void*)0))
28431 xmlSchemaSAXHandleText(ctxt->ctxt, ch, len);
28432}
28433
28434static void
28435cdataBlockSplit(void *ctx, const xmlChar *value, int len)
28436{
28437 xmlSchemaSAXPlugPtr ctxt = (xmlSchemaSAXPlugPtr) ctx;
28438 if (ctxt == NULL((void*)0))
28439 return;
28440 if ((ctxt->user_sax != NULL((void*)0)) &&
28441 (ctxt->user_sax->cdataBlock != NULL((void*)0)))
28442 ctxt->user_sax->cdataBlock(ctxt->user_data, value, len);
28443 if (ctxt->ctxt != NULL((void*)0))
28444 xmlSchemaSAXHandleCDataSection(ctxt->ctxt, value, len);
28445}
28446
28447static void
28448referenceSplit(void *ctx, const xmlChar *name)
28449{
28450 xmlSchemaSAXPlugPtr ctxt = (xmlSchemaSAXPlugPtr) ctx;
28451 if (ctxt == NULL((void*)0))
28452 return;
28453 if ((ctxt != NULL((void*)0)) && (ctxt->user_sax != NULL((void*)0)) &&
28454 (ctxt->user_sax->reference != NULL((void*)0)))
28455 ctxt->user_sax->reference(ctxt->user_data, name);
28456 if (ctxt->ctxt != NULL((void*)0))
28457 xmlSchemaSAXHandleReference(ctxt->user_data, name);
28458}
28459
28460static void
28461startElementNsSplit(void *ctx, const xmlChar * localname,
28462 const xmlChar * prefix, const xmlChar * URI,
28463 int nb_namespaces, const xmlChar ** namespaces,
28464 int nb_attributes, int nb_defaulted,
28465 const xmlChar ** attributes) {
28466 xmlSchemaSAXPlugPtr ctxt = (xmlSchemaSAXPlugPtr) ctx;
28467 if (ctxt == NULL((void*)0))
28468 return;
28469 if ((ctxt->user_sax != NULL((void*)0)) &&
28470 (ctxt->user_sax->startElementNs != NULL((void*)0)))
28471 ctxt->user_sax->startElementNs(ctxt->user_data, localname, prefix,
28472 URI, nb_namespaces, namespaces,
28473 nb_attributes, nb_defaulted,
28474 attributes);
28475 if (ctxt->ctxt != NULL((void*)0))
28476 xmlSchemaSAXHandleStartElementNs(ctxt->ctxt, localname, prefix,
28477 URI, nb_namespaces, namespaces,
28478 nb_attributes, nb_defaulted,
28479 attributes);
28480}
28481
28482static void
28483endElementNsSplit(void *ctx, const xmlChar * localname,
28484 const xmlChar * prefix, const xmlChar * URI) {
28485 xmlSchemaSAXPlugPtr ctxt = (xmlSchemaSAXPlugPtr) ctx;
28486 if (ctxt == NULL((void*)0))
28487 return;
28488 if ((ctxt->user_sax != NULL((void*)0)) &&
28489 (ctxt->user_sax->endElementNs != NULL((void*)0)))
28490 ctxt->user_sax->endElementNs(ctxt->user_data, localname, prefix, URI);
28491 if (ctxt->ctxt != NULL((void*)0))
28492 xmlSchemaSAXHandleEndElementNs(ctxt->ctxt, localname, prefix, URI);
28493}
28494
28495/**
28496 * xmlSchemaSAXPlug:
28497 * @ctxt: a schema validation context
28498 * @sax: a pointer to the original xmlSAXHandlerPtr
28499 * @user_data: a pointer to the original SAX user data pointer
28500 *
28501 * Plug a SAX based validation layer in a SAX parsing event flow.
28502 * The original @saxptr and @dataptr data are replaced by new pointers
28503 * but the calls to the original will be maintained.
28504 *
28505 * Returns a pointer to a data structure needed to unplug the validation layer
28506 * or NULL in case of errors.
28507 */
28508xmlSchemaSAXPlugPtr
28509xmlSchemaSAXPlug(xmlSchemaValidCtxtPtr ctxt,
28510 xmlSAXHandlerPtr *sax, void **user_data)
28511{
28512 xmlSchemaSAXPlugPtr ret;
28513 xmlSAXHandlerPtr old_sax;
28514
28515 if ((ctxt == NULL((void*)0)) || (sax == NULL((void*)0)) || (user_data == NULL((void*)0)))
28516 return(NULL((void*)0));
28517
28518 /*
28519 * We only allow to plug into SAX2 event streams
28520 */
28521 old_sax = *sax;
28522 if ((old_sax != NULL((void*)0)) && (old_sax->initialized != XML_SAX2_MAGIC0xDEEDBEAF))
28523 return(NULL((void*)0));
28524 if ((old_sax != NULL((void*)0)) &&
28525 (old_sax->startElementNs == NULL((void*)0)) && (old_sax->endElementNs == NULL((void*)0)) &&
28526 ((old_sax->startElement != NULL((void*)0)) || (old_sax->endElement != NULL((void*)0))))
28527 return(NULL((void*)0));
28528
28529 /*
28530 * everything seems right allocate the local data needed for that layer
28531 */
28532 ret = (xmlSchemaSAXPlugPtr) xmlMalloc(sizeof(xmlSchemaSAXPlugStruct));
28533 if (ret == NULL((void*)0)) {
28534 return(NULL((void*)0));
28535 }
28536 memset(ret, 0, sizeof(xmlSchemaSAXPlugStruct));
28537 ret->magic = XML_SAX_PLUG_MAGIC0xdc43ba21;
28538 ret->schemas_sax.initialized = XML_SAX2_MAGIC0xDEEDBEAF;
28539 ret->ctxt = ctxt;
28540 ret->user_sax_ptr = sax;
28541 ret->user_sax = old_sax;
28542 if (old_sax == NULL((void*)0)) {
28543 /*
28544 * go direct, no need for the split block and functions.
28545 */
28546 ret->schemas_sax.startElementNs = xmlSchemaSAXHandleStartElementNs;
28547 ret->schemas_sax.endElementNs = xmlSchemaSAXHandleEndElementNs;
28548 /*
28549 * Note that we use the same text-function for both, to prevent
28550 * the parser from testing for ignorable whitespace.
28551 */
28552 ret->schemas_sax.ignorableWhitespace = xmlSchemaSAXHandleText;
28553 ret->schemas_sax.characters = xmlSchemaSAXHandleText;
28554
28555 ret->schemas_sax.cdataBlock = xmlSchemaSAXHandleCDataSection;
28556 ret->schemas_sax.reference = xmlSchemaSAXHandleReference;
28557
28558 ret->user_data = ctxt;
28559 *user_data = ctxt;
28560 } else {
28561 /*
28562 * for each callback unused by Schemas initialize it to the Split
28563 * routine only if non NULL in the user block, this can speed up
28564 * things at the SAX level.
28565 */
28566 if (old_sax->internalSubset != NULL((void*)0))
28567 ret->schemas_sax.internalSubset = internalSubsetSplit;
28568 if (old_sax->isStandalone != NULL((void*)0))
28569 ret->schemas_sax.isStandalone = isStandaloneSplit;
28570 if (old_sax->hasInternalSubset != NULL((void*)0))
28571 ret->schemas_sax.hasInternalSubset = hasInternalSubsetSplit;
28572 if (old_sax->hasExternalSubset != NULL((void*)0))
28573 ret->schemas_sax.hasExternalSubset = hasExternalSubsetSplit;
28574 if (old_sax->resolveEntity != NULL((void*)0))
28575 ret->schemas_sax.resolveEntity = resolveEntitySplit;
28576 if (old_sax->getEntity != NULL((void*)0))
28577 ret->schemas_sax.getEntity = getEntitySplit;
28578 if (old_sax->entityDecl != NULL((void*)0))
28579 ret->schemas_sax.entityDecl = entityDeclSplit;
28580 if (old_sax->notationDecl != NULL((void*)0))
28581 ret->schemas_sax.notationDecl = notationDeclSplit;
28582 if (old_sax->attributeDecl != NULL((void*)0))
28583 ret->schemas_sax.attributeDecl = attributeDeclSplit;
28584 if (old_sax->elementDecl != NULL((void*)0))
28585 ret->schemas_sax.elementDecl = elementDeclSplit;
28586 if (old_sax->unparsedEntityDecl != NULL((void*)0))
28587 ret->schemas_sax.unparsedEntityDecl = unparsedEntityDeclSplit;
28588 if (old_sax->setDocumentLocator != NULL((void*)0))
28589 ret->schemas_sax.setDocumentLocator = setDocumentLocatorSplit;
28590 if (old_sax->startDocument != NULL((void*)0))
28591 ret->schemas_sax.startDocument = startDocumentSplit;
28592 if (old_sax->endDocument != NULL((void*)0))
28593 ret->schemas_sax.endDocument = endDocumentSplit;
28594 if (old_sax->processingInstruction != NULL((void*)0))
28595 ret->schemas_sax.processingInstruction = processingInstructionSplit;
28596 if (old_sax->comment != NULL((void*)0))
28597 ret->schemas_sax.comment = commentSplit;
28598 if (old_sax->warning != NULL((void*)0))
28599 ret->schemas_sax.warning = warningSplit;
28600 if (old_sax->error != NULL((void*)0))
28601 ret->schemas_sax.error = errorSplit;
28602 if (old_sax->fatalError != NULL((void*)0))
28603 ret->schemas_sax.fatalError = fatalErrorSplit;
28604 if (old_sax->getParameterEntity != NULL((void*)0))
28605 ret->schemas_sax.getParameterEntity = getParameterEntitySplit;
28606 if (old_sax->externalSubset != NULL((void*)0))
28607 ret->schemas_sax.externalSubset = externalSubsetSplit;
28608
28609 /*
28610 * the 6 schemas callback have to go to the splitter functions
28611 * Note that we use the same text-function for ignorableWhitespace
28612 * if possible, to prevent the parser from testing for ignorable
28613 * whitespace.
28614 */
28615 ret->schemas_sax.characters = charactersSplit;
28616 if ((old_sax->ignorableWhitespace != NULL((void*)0)) &&
28617 (old_sax->ignorableWhitespace != old_sax->characters))
28618 ret->schemas_sax.ignorableWhitespace = ignorableWhitespaceSplit;
28619 else
28620 ret->schemas_sax.ignorableWhitespace = charactersSplit;
28621 ret->schemas_sax.cdataBlock = cdataBlockSplit;
28622 ret->schemas_sax.reference = referenceSplit;
28623 ret->schemas_sax.startElementNs = startElementNsSplit;
28624 ret->schemas_sax.endElementNs = endElementNsSplit;
28625
28626 ret->user_data_ptr = user_data;
28627 ret->user_data = *user_data;
28628 *user_data = ret;
28629 }
28630
28631 /*
28632 * plug the pointers back.
28633 */
28634 *sax = &(ret->schemas_sax);
28635 ctxt->sax = *sax;
28636 ctxt->flags |= XML_SCHEMA_VALID_CTXT_FLAG_STREAM1;
28637 xmlSchemaPreRun(ctxt);
28638 return(ret);
28639}
28640
28641/**
28642 * xmlSchemaSAXUnplug:
28643 * @plug: a data structure returned by xmlSchemaSAXPlug
28644 *
28645 * Unplug a SAX based validation layer in a SAX parsing event flow.
28646 * The original pointers used in the call are restored.
28647 *
28648 * Returns 0 in case of success and -1 in case of failure.
28649 */
28650int
28651xmlSchemaSAXUnplug(xmlSchemaSAXPlugPtr plug)
28652{
28653 xmlSAXHandlerPtr *sax;
28654 void **user_data;
28655
28656 if ((plug == NULL((void*)0)) || (plug->magic != XML_SAX_PLUG_MAGIC0xdc43ba21))
28657 return(-1);
28658 plug->magic = 0;
28659
28660 xmlSchemaPostRun(plug->ctxt);
28661 /* restore the data */
28662 sax = plug->user_sax_ptr;
28663 *sax = plug->user_sax;
28664 if (plug->user_sax != NULL((void*)0)) {
28665 user_data = plug->user_data_ptr;
28666 *user_data = plug->user_data;
28667 }
28668
28669 /* free and return */
28670 xmlFree(plug);
28671 return(0);
28672}
28673
28674/**
28675 * xmlSchemaValidateSetLocator:
28676 * @vctxt: a schema validation context
28677 * @f: the locator function pointer
28678 * @ctxt: the locator context
28679 *
28680 * Allows to set a locator function to the validation context,
28681 * which will be used to provide file and line information since
28682 * those are not provided as part of the SAX validation flow
28683 * Setting @f to NULL disable the locator.
28684 */
28685
28686void
28687xmlSchemaValidateSetLocator(xmlSchemaValidCtxtPtr vctxt,
28688 xmlSchemaValidityLocatorFunc f,
28689 void *ctxt)
28690{
28691 if (vctxt == NULL((void*)0)) return;
28692 vctxt->locFunc = f;
28693 vctxt->locCtxt = ctxt;
28694}
28695
28696/**
28697 * xmlSchemaValidateStreamLocator:
28698 * @ctx: the xmlTextReaderPtr used
28699 * @file: returned file information
28700 * @line: returned line information
28701 *
28702 * Internal locator function for the readers
28703 *
28704 * Returns 0 in case the Schema validation could be (de)activated and
28705 * -1 in case of error.
28706 */
28707static int
28708xmlSchemaValidateStreamLocator(void *ctx, const char **file,
28709 unsigned long *line) {
28710 xmlParserCtxtPtr ctxt;
28711
28712 if ((ctx == NULL((void*)0)) || ((file == NULL((void*)0)) && (line == NULL((void*)0))))
28713 return(-1);
28714
28715 if (file != NULL((void*)0))
28716 *file = NULL((void*)0);
28717 if (line != NULL((void*)0))
28718 *line = 0;
28719
28720 ctxt = (xmlParserCtxtPtr) ctx;
28721 if (ctxt->input != NULL((void*)0)) {
28722 if (file != NULL((void*)0))
28723 *file = ctxt->input->filename;
28724 if (line != NULL((void*)0))
28725 *line = ctxt->input->line;
28726 return(0);
28727 }
28728 return(-1);
28729}
28730
28731/**
28732 * xmlSchemaValidateStreamInternal:
28733 * @ctxt: a schema validation context
28734 * @pctxt: a parser context
28735 *
28736 * Returns 0 if the document is schemas valid, a positive error code
28737 * number otherwise and -1 in case of internal or API error.
28738 */
28739static int
28740xmlSchemaValidateStreamInternal(xmlSchemaValidCtxtPtr ctxt,
28741 xmlParserCtxtPtr pctxt) {
28742 xmlSchemaSAXPlugPtr plug = NULL((void*)0);
28743 int ret;
28744
28745 pctxt->linenumbers = 1;
28746 xmlSchemaValidateSetLocator(ctxt, xmlSchemaValidateStreamLocator, pctxt);
28747
28748 ctxt->parserCtxt = pctxt;
28749 ctxt->input = pctxt->input->buf;
28750
28751 /*
28752 * Plug the validation and launch the parsing
28753 */
28754 plug = xmlSchemaSAXPlug(ctxt, &(pctxt->sax), &(pctxt->userData));
28755 if (plug == NULL((void*)0)) {
28756 ret = -1;
28757 goto done;
28758 }
28759 ctxt->input = pctxt->input->buf;
28760 ctxt->sax = pctxt->sax;
28761 ctxt->flags |= XML_SCHEMA_VALID_CTXT_FLAG_STREAM1;
28762 ret = xmlSchemaVStart(ctxt);
28763
28764 if ((ret == 0) && (! ctxt->parserCtxt->wellFormed)) {
28765 ret = ctxt->parserCtxt->errNo;
28766 if (ret == 0)
28767 ret = 1;
28768 }
28769
28770done:
28771 ctxt->parserCtxt = NULL((void*)0);
28772 ctxt->sax = NULL((void*)0);
28773 ctxt->input = NULL((void*)0);
28774 if (plug != NULL((void*)0)) {
28775 xmlSchemaSAXUnplug(plug);
28776 }
28777 return (ret);
28778}
28779
28780/**
28781 * xmlSchemaValidateStream:
28782 * @ctxt: a schema validation context
28783 * @input: the input to use for reading the data
28784 * @enc: an optional encoding information
28785 * @sax: a SAX handler for the resulting events
28786 * @user_data: the context to provide to the SAX handler.
28787 *
28788 * Validate an input based on a flow of SAX event from the parser
28789 * and forward the events to the @sax handler with the provided @user_data
28790 * the user provided @sax handler must be a SAX2 one.
28791 *
28792 * Returns 0 if the document is schemas valid, a positive error code
28793 * number otherwise and -1 in case of internal or API error.
28794 */
28795int
28796xmlSchemaValidateStream(xmlSchemaValidCtxtPtr ctxt,
28797 xmlParserInputBufferPtr input, xmlCharEncoding enc,
28798 xmlSAXHandlerPtr sax, void *user_data)
28799{
28800 xmlParserCtxtPtr pctxt = NULL((void*)0);
28801 xmlParserInputPtr inputStream = NULL((void*)0);
28802 int ret;
28803
28804 if ((ctxt == NULL((void*)0)) || (input == NULL((void*)0)))
28805 return (-1);
28806
28807 /*
28808 * prepare the parser
28809 */
28810 if (sax != NULL((void*)0)) {
28811 pctxt = xmlNewSAXParserCtxt(sax, user_data);
28812 if (pctxt == NULL((void*)0))
28813 return (-1);
28814 } else {
28815 pctxt = xmlNewParserCtxt();
28816 if (pctxt == NULL((void*)0))
28817 return (-1);
28818 /* We really want pctxt->sax to be NULL here. */
28819 xmlFree(pctxt->sax);
28820 pctxt->sax = NULL((void*)0);
28821 }
28822#if 0
28823 if (options)
28824 xmlCtxtUseOptions(pctxt, options);
28825#endif
28826
28827 inputStream = xmlNewIOInputStream(pctxt, input, enc);;
28828 if (inputStream == NULL((void*)0)) {
28829 ret = -1;
28830 goto done;
28831 }
28832 inputPush(pctxt, inputStream);
28833
28834 ctxt->enc = enc;
28835
28836 ret = xmlSchemaValidateStreamInternal(ctxt, pctxt);
28837
28838done:
28839 /* cleanup */
28840 if (pctxt != NULL((void*)0)) {
28841 xmlFreeParserCtxt(pctxt);
28842 }
28843 return (ret);
28844}
28845
28846/**
28847 * xmlSchemaValidateFile:
28848 * @ctxt: a schema validation context
28849 * @filename: the URI of the instance
28850 * @options: a future set of options, currently unused
28851 *
28852 * Do a schemas validation of the given resource, it will use the
28853 * SAX streamable validation internally.
28854 *
28855 * Returns 0 if the document is valid, a positive error code
28856 * number otherwise and -1 in case of an internal or API error.
28857 */
28858int
28859xmlSchemaValidateFile(xmlSchemaValidCtxtPtr ctxt,
28860 const char * filename,
28861 int options ATTRIBUTE_UNUSED__attribute__((unused)))
28862{
28863 int ret;
28864 xmlParserCtxtPtr pctxt = NULL((void*)0);
28865
28866 if ((ctxt == NULL((void*)0)) || (filename == NULL((void*)0)))
28867 return (-1);
28868
28869 pctxt = xmlCreateURLParserCtxt(filename, 0);
28870 if (pctxt == NULL((void*)0))
28871 return (-1);
28872 /* We really want pctxt->sax to be NULL here. */
28873 xmlFree(pctxt->sax);
28874 pctxt->sax = NULL((void*)0);
28875 ret = xmlSchemaValidateStreamInternal(ctxt, pctxt);
28876 xmlFreeParserCtxt(pctxt);
28877 return (ret);
28878}
28879
28880/**
28881 * xmlSchemaValidCtxtGetParserCtxt:
28882 * @ctxt: a schema validation context
28883 *
28884 * allow access to the parser context of the schema validation context
28885 *
28886 * Returns the parser context of the schema validation context or NULL
28887 * in case of error.
28888 */
28889xmlParserCtxtPtr
28890xmlSchemaValidCtxtGetParserCtxt(xmlSchemaValidCtxtPtr ctxt)
28891{
28892 if (ctxt == NULL((void*)0))
28893 return(NULL((void*)0));
28894 return (ctxt->parserCtxt);
28895}
28896
28897#endif /* LIBXML_SCHEMAS_ENABLED */